最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to avoid indented nested promises? - Stack Overflow

programmeradmin1浏览0评论

I heard that promises are supposed to be linear in code in opposed to callbacks ("callback hell").

Though I still have a scenario similar to callback hell and hoping promises can make their promise and have a linear syntax equivalent to this problem code.

Given promises p(), q(),w() consider this code:

p().then(() => {
    q().then(() => {
       w().then(() => {
           // do something
       })
    })
})

Can we make an equivalent code which is not indented for every nested promise?

I heard that promises are supposed to be linear in code in opposed to callbacks ("callback hell").

Though I still have a scenario similar to callback hell and hoping promises can make their promise and have a linear syntax equivalent to this problem code.

Given promises p(), q(),w() consider this code:

p().then(() => {
    q().then(() => {
       w().then(() => {
           // do something
       })
    })
})

Can we make an equivalent code which is not indented for every nested promise?

Share Improve this question edited Dec 30, 2020 at 23:26 asked Dec 30, 2020 at 23:00 user12421682user12421682 1
  • If the subsequent promises rely on the preceding promises, they have to indent. Otherwise look into using async/await to change your styling. – Taplar Commented Dec 30, 2020 at 23:03
Add a ment  | 

3 Answers 3

Reset to default 8

You should not nest the .then() handlers but let each .then() create and return a new Promise. This is how it was designed to work, otherwise you are still in the callback hell, now the version with promises. No big difference.

The code should be like this:

p()
  .then(() => {
    return q();
  })
  .then(() => {
    return w();
  })
  .then(() => {
    // do something
  });

If all that the .then() handlers do is to call the next function you can write it in a simpler form (read about arrow functions):

p()
  .then(() => q())
  .then(() => w())
  .then(() => {
    // do something
  });

Even more, if q and w are called without arguments, the code could be as simple as:

p()
  .then(q)
  .then(w)
  .then(() => {
    // do something
  });

Or you can go the extra mile and instead of using .then() and .catch() you use await. The code bees even more clear and easy to read:

try {
  await p();
  await q();
  await w();
  // do something
} catch (err) {
  // write here the code you would write in the handler you pass to `.catch()
  // in the approach that uses Promises
}

Remarks

If the code above, using await, is used in a function then that function must be an async function (just put async in front of its definition).

The code that uses await may or may not be used outside of a function (i.e. at module's top level) depending on the runtime you use to run it (browser, Node.js etc).

As another user mentioned, you could use async/await but another option is just to slightly restructure what you have. Here are some examples of what could work – depending on where and when you need certain pieces of data:

p()
  .then(q)
  .then(w)

// OR

p()
  .then(() => q())
  .then(() => w())

Obviously this gets a little more plicated if w() needs data from both p() and q() but that's the gist of it.

You could try using async/await, which leaves a more cleaner code. It would be like this:

(async () => {
    try {
        await p();
        await q();
        await w();
    } catch (e) {
        // handle error
    }
})()

If there is no dependency between each promise you can use await Promise.all in order to do "all or nothing". In any other case, you can store the returned value and pass it to the next function in order to be used if needed.

发布评论

评论列表(0)

  1. 暂无评论