我听说承诺在代码中应该是线性的,而不是回调(“回调地狱”)。
尽管我仍然有一个类似于回调地狱的场景,并希望 promise 能够做出他们的承诺,并具有与此问题代码等效的线性语法。
鉴于承诺 p()
、q()
、w()
,请考虑以下代码:
p().then(() => {
q().then(() => {
w().then(() => {
// do something
})
})
})
我们能否编写一个不为每个嵌套 promise 缩进的等效代码?
答案 0 :(得分:3)
正如另一位用户所提到的,您可以使用 async/await
,但另一种选择只是稍微重组您所拥有的内容。以下是一些可行的示例,具体取决于您何时何地需要某些数据:
p()
.then(q)
.then(w)
// OR
p()
.then(() => q())
.then(() => w())
显然,如果 w()
需要来自 p()
和 q()
的数据,这会变得有点复杂,但这就是它的要点。
答案 1 :(得分:2)
您不应嵌套 .then()
处理程序,而应让每个 .then()
创建并返回一个新的 Promise
。这就是它的设计方式,否则你仍然在回调地狱中,现在是带有承诺的版本。没有太大区别。
代码应该是这样的:
p()
.then(() => {
return q();
})
.then(() => {
return w();
})
.then(() => {
// do something
});
如果 .then()
处理程序所做的只是调用下一个函数,您可以用更简单的形式编写它(阅读 arrow functions):
p()
.then(() => q())
.then(() => w())
.then(() => {
// do something
});
更重要的是,如果在没有参数的情况下调用 q
和 w
,则代码可以像这样简单:
p()
.then(q)
.then(w)
.then(() => {
// do something
});
或者您可以加倍努力,而不是使用 .then()
和 .catch()
,而是使用 await
。代码变得更加清晰易读:
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
}
如果上面使用 await
的代码在函数中使用,则该函数必须是 async
function(只需将 async
放在其定义前面)。
使用 await
may or may not be used outside of a function 的代码(即在模块的顶层)取决于您用来运行它的运行时(浏览器、Node.js 等)。
答案 2 :(得分:1)
您可以尝试使用 async/await
,这样代码会更简洁。应该是这样的:
(async () => {
try {
await p();
await q();
await w();
} catch (e) {
// handle error
}
})()
如果每个 promise 之间没有依赖关系,您可以使用 await Promise.all
来执行“全有或全无”。在任何其他情况下,您可以存储返回值并将其传递给下一个函数,以便在需要时使用。