如何避免缩进嵌套承诺?
How to avoid indented nested promises?
我听说 promise 在代码中应该是线性的,而不是回调(“回调地狱”)。
虽然我还有一个类似于回调地狱的场景,希望promise能够实现他们的promise,并且有一个等价于这个问题代码的线性语法。
给定承诺 p()
、q()
、w()
考虑此代码:
p().then(() => {
q().then(() => {
w().then(() => {
// do something
})
})
})
我们能否为每个嵌套的 promise 制作一个不缩进的等效代码?
您可以尝试使用 async/await
,这样可以留下更简洁的代码。应该是这样的:
(async () => {
try {
await p();
await q();
await w();
} catch (e) {
// handle error
}
})()
如果每个承诺之间没有依赖关系,您可以使用 await Promise.all
来“全有或全无”。在任何其他情况下,您可以存储返回值并将其传递给下一个函数,以便在需要时使用。
正如另一位用户提到的,您可以使用 async/await
,但另一种选择只是稍微重组您拥有的内容。以下是一些可行的示例——取决于您何时何地需要某些数据:
p()
.then(q)
.then(w)
// OR
p()
.then(() => q())
.then(() => w())
显然,如果 w()
需要来自 p()
和 q()
的数据,这会变得有点复杂,但这就是它的要点。
您不应嵌套 .then()
处理程序,而应让每个 .then()
创建并 return 一个新的 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()
and .catch()
you use 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等)。
我听说 promise 在代码中应该是线性的,而不是回调(“回调地狱”)。
虽然我还有一个类似于回调地狱的场景,希望promise能够实现他们的promise,并且有一个等价于这个问题代码的线性语法。
给定承诺 p()
、q()
、w()
考虑此代码:
p().then(() => {
q().then(() => {
w().then(() => {
// do something
})
})
})
我们能否为每个嵌套的 promise 制作一个不缩进的等效代码?
您可以尝试使用 async/await
,这样可以留下更简洁的代码。应该是这样的:
(async () => {
try {
await p();
await q();
await w();
} catch (e) {
// handle error
}
})()
如果每个承诺之间没有依赖关系,您可以使用 await Promise.all
来“全有或全无”。在任何其他情况下,您可以存储返回值并将其传递给下一个函数,以便在需要时使用。
正如另一位用户提到的,您可以使用 async/await
,但另一种选择只是稍微重组您拥有的内容。以下是一些可行的示例——取决于您何时何地需要某些数据:
p()
.then(q)
.then(w)
// OR
p()
.then(() => q())
.then(() => w())
显然,如果 w()
需要来自 p()
和 q()
的数据,这会变得有点复杂,但这就是它的要点。
您不应嵌套 .then()
处理程序,而应让每个 .then()
创建并 return 一个新的 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()
and .catch()
you use 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等)。