等待承诺链有什么问题?

What's wrong with awaiting a promise chain?

我正在开发一个 Angular 6 应用程序,我被告知以下是一个反模式:

await someFunction().then(result => {
    console.log(result);
});

我意识到等待承诺链是没有意义的。如果 someFunction() returns 是一个 promise,那么如果你正在等待它,则不需要 promise 链。你可以这样做:

const result = await someFunction();
console.log(result);

但有人告诉我等待承诺链会导致错误,或者它会破坏我的代码。如果上面的第一个代码片段与第二个代码片段做同样的事情,那么使用哪个代码片段有什么关系。第一个片段介绍了哪些第二个片段没有介绍的危险?

在幕后,async/await 只是承诺。

也就是说,当您的代码如下所示时:

const result = await myAsyncFunction();   
console.log(result): 

这与写作完全一样:

myAsyncFunction().then(data => {
   const result = data; 
   console.log(result); 
}); 

那么您不应该混合使用 async/await 和 .then 链的原因是因为它会造成混淆。

最好只选择一种风格,并坚持下去。

当你选择一个时 - 你也可以选择 async/await - 它更容易理解。

如果您的 then 代码 return 承诺而不是调用 console.log,您的第一个示例会 await,但第二个示例不会。

当您使用 async/await 时,您将在 try/catch 块中发现不合格品。您的代码将更少嵌套且更清晰。

使用 then 通常会导致更多嵌套,代码更难阅读。

你可以 await 任何东西,无论它 return 是否 promise。有时,这种面向未来的调用可能有一天会变成异步的方法,或者只是 return 一个没有声明异步的承诺。

缺点是复杂性、性能和兼容性,与优点相比,所有这些都显得苍白无力。

我发现,如果你在调用函数后依赖于函数的 return 值,并且它是或可能最终变成异步的,那么用 await 装饰你的函数调用你的心,无论是不是当前异步或 return 是一个承诺。

I’m being told awaiting a promise chain will break things in my code.

不一定,你的两个代码片段确实工作相同(只要 someFunction() 真的 return 是一个承诺)。

What does it matter which one is used. What dangers does the first snippet introduce that the second one doesn’t?

更难理解和维护,混合不同的风格很混乱。混乱导致错误。

考虑到您需要在 console.log() 调用的位置添加另一个 promise 调用,甚至是函数中的条件 return。你能像在函数的其他地方一样在回调中使用 await 吗,你是否需要 return 来自 then 回调的结果,甚至可以从外部 return功能?所有这些问题甚至都没有出现在第一个片段中。虽然您的玩具示例可以轻松回答这些问题,但在具有更复杂和嵌套控制流的实际代码中可能并不那么容易。

所以你应该更喜欢更简洁干净的那个。坚持 await 以获得 一致性 ,避免 then in async functions1.

1:当然,规则总是有例外的。我会说在某些情况下使用 catch 或第二个 then 回调时 更干净。