问题
I’m working on an Angular 6 application and I’ve been told the following is an anti-pattern:
await someFunction().then(result => {
console.log(result);
});
I realize that it is pointless to await a promise chain. If someFunction() returns a promise, you don’t need a promise chain if you’re awaiting it. You can do this:
const result = await someFunction();
console.log(result);
But I’m being told awaiting a promise chain can cause bugs, or that it will break things in my code. If the first code snippet above does the same thing as the second snippet, what does it matter which one is used. What dangers does the first snippet introduce that the second one doesn’t?
回答1:
Under the hood, async/await is just promises.
That is, when you have some code that looks like:
const result = await myAsyncFunction();
console.log(result):
That's exactly the same as writing:
myAsyncFunction().then(data => {
const result = data;
console.log(result);
});
The reason then - that you shouldn't mix async/await and .then
chains - is because it's confusing.
It's better to just pick one style, and stick to it.
And while you're picking one - you might as well pick async/await - it's more understandable.
回答2:
I’m being told awaiting a promise chain will break things in my code.
Not necessarily, your two code snippets do indeed work the same (as long as someFunction()
really returns a promise).
What does it matter which one is used. What dangers does the first snippet introduce that the second one doesn’t?
It's harder to understand and maintain, it's confusing to mix different styles. Confusion leads to bugs.
Consider that you would need to add another promise call at the location of the console.log()
call, or even a conditional return from the function. Can you use await
in the callback like elsewhere in the function, do you need to return
the result from the then
callback, is it even possible to return
from the outer function? All these questions don't even come up in the first snippet. And while they can be easily answered for your toy example, it might not be as easy in real code with more complex and nested control flow.
So you should prefer the more concise and clean one. Stick to await
for consistency, avoid then
in async function
s1.
1: Of course, there's always an exception to the rule. I would say that it's cleaner to use promise chaining for error handling in some cases where you would use catch
or the second then
callback.
回答3:
If your then
code returned a promise instead of calling console.log
, your first example would await
, but your second example would not.
When you use async/await
, you will catch your rejects in try/catch
blocks. Your code will be less nested and clearer.
Using then
often results in more nesting, and harder to read code.
You can await
anything, whether or not it returns a promise
. Sometimes this future-proofs calling a method that may one day become async or just return a promise without declaring async.
The downsides are complexity, performance, and compatibility, all of which pale in comparison to the gains.
I find that if you rely on a function's return value after calling it, and it is or may eventually become asynchronous, decorate calling your functions with await
to your heart's delight, whether or not it is current async or returns a promise.
来源:https://stackoverflow.com/questions/54385676/whats-wrong-with-awaiting-a-promise-chain