当从一个异步函数的promise返回时,我们可以使用return await promise等待 promise 解析完,也可以直接返回它 return promise。
async function func1() { const promise = asyncOperation(); return await promise; } // vs async function func2() { const promise = asyncOperation(); return promise; }
这两个表达式都是有效的。然而,在某些情况下,这些表达式的表现会有所不同吗?我们往下看。
1. 相同的行为
为了找到这两个表达式(返回 await promise vs return promise)之间的区别,我们需要一个辅助函数 delayedDivide(n1, n2)。
该函数除2个数字,并返回包含在promise中的除法结果:
function promisedDivision(n1, n2) { if (n2 === 0) { return Promise.reject(new Error('Cannot divide by 0')); } else { return Promise.resolve(n1 / n2); } }
如果第二个参数(除数)是 0,该函数返回一个 reject,因为除以 0 是不可能的。
定义了辅助函数之后,我们来跑几个例子。
下面的函数divideWithAwait()使用return await promisedDivision(6,2)表达式来返回包裹在promise中的 6 除以 2 的除法
async function divideWithAwait() { return await promisedDivision(6, 2); } async function run() { const result = await divideWithAwait(); console.log(result); // logs 3 } run();
事例地址:https://codesandbox.io/s/with-await-resolved-mdzz5?file=/src/index.js
在run()函数中,await divideWithAwait()表达式的计算结果为除法结果 3,一切正常。
如果有返回不带await关键字,结果又会怎么样呢?
async function divideWithoutAwait() { return promisedDivision(6, 2); } async function run() { const result = await divideWithoutAwait(); console.log(result); // logs 3 } run();
事例地址:https://codesandbox.io/s/without-await-resolved-u06sb
即使在divideWithoutAwait() 中没有使用 await 关键字,run() 函数中的表达式awaitdivideWithoutAwait() 的结果也是正确的。
在这一步,我们已经看到使用return await promise和return promise并没有什么不同。
2.不同行为
现在我们采用另一种方法,要使函数 promisedDivision(n1, n2)返回一个被拒绝的promise,我们将第二个参数设置为 0。
因为promisedDivis
async function divideWithAwait() { try { return await promisedDivision(5, 0); } catch (error) { // Rejection caught console.log(error); // logs Error('Cannot divide by 0') } } async function run() { const result = await divideWithAwait(); } run(); ion(n1, 0) 会返回一个异常
事例地址:https://codesandbox.io/s/with-await-rejected-ihxg5?file=/src/index.js
如果没有 await,结果又会怎么样?
,我们使用 try {... } catch (error) {...}。
async function divideWithoutAwait() { try { return promisedDivision(5, 0); } catch (error) { // Rejection NOT caught console.log(error); } } async function run() { const result = await divideWithoutAwait(); } run(); // Uncaught Error: Cannot divide by 0
事例地址:https://codesandbox.io/s/without-await-rejected-477nr?file=/src/index.js
然而,这次,catch(error) { ... }并没有捕捉到异常。
到这,我们就使用return await promise和return promise之间的主要区别了。