显著的区别:Promise拒绝在不同位置被处理
return somePromise
将会将 somePromise 传递给调用栈,并且在调用栈上使用 await
等待 somePromise 的解决结果(如果有)。因此,如果 somePromise 被拒绝,它将不会被本地捕获块处理,而是被调用方的捕获块处理。
async function foo () {
try {
return Promise.reject();
} catch (e) {
console.log('IN');
}
}
(async function main () {
try {
let a = await foo();
} catch (e) {
console.log('OUT');
}
})();
return await somePromise
将首先等待 somePromise 在本地settled。因此,值或异常将首先在本地处理。 => 如果 somePromise
被拒绝,那么本地 catch 块将被执行。
async function foo () {
try {
return await Promise.reject();
} catch (e) {
console.log('IN');
}
}
(async function main () {
try {
let a = await foo();
} catch (e) {
console.log('OUT');
}
})();
原因: return await Promise
同时在局部和外部都需要等待,return Promise
只在外部等待
详细步骤:
return Promise
async function delay1Second() {
return delay(1000);
}
- 调用
delay1Second()
函数;
const result = await delay1Second();
delay1Second()
函数内,delay(1000)
立即返回一个promise对象,其[[PromiseStatus]]
值为'pending'。我们称之为delayPromise
。
async function delay1Second() {
return delayPromise;
}
- 异步函数将在
Promise.resolve()
内封装它们的返回值(来源)。因为delay1Second
是一个异步函数,所以我们有:
const result = await Promise.resolve(delayPromise);
Promise.resolve(delayPromise)
返回 delayPromise
而不做任何事情,因为输入已经是一个promise对象(见MDN Promise.resolve):
const result = await delayPromise;
await
等待 delayPromise
被解决。
- 如果
delayPromise
被 PromiseValue=1 这个值所满足:
const result = 1;
返回一个等待的 Promise
async function delay1Second() {
return await delay(1000);
}
- 调用
delay1Second()
函数;
const result = await delay1Second();
- 在
delay1Second()
函数内部,delay(1000)
函数立即返回一个Promise,并且[[PromiseStatus]]: 'pending'
,我们称之为delayPromise
。
async function delay1Second() {
return await delayPromise;
}
- 本地等待将会等待
delayPromise
被解决。
- 情况1:
delayPromise
被 PromiseValue=1 解决:
async function delay1Second() {
return 1;
}
const result = await Promise.resolve(1);
const result = await newPromise;
const result = 1;
const result = await Promise.resolve(-1);
const result = await newPromise;
const result = -1;
术语表:
- Settle:当
Promise.[[PromiseStatus]]
从 pending
变为 resolved
或者 rejected
时,表示 Promise 完成了状态转换。
return promise
)示例中删除async
。 - Stephen Clearypromise.then(() => nestedPromise)
会展开和“跟随”nestedPromise
。有趣的是,它与C#中的嵌套任务不同,我们需要使用Unwrap
函数。顺便提一下,在 这里 看起来await somePromise
调用了Promise.resolve(somePromise).then
,而不仅仅是somePromise.then
,具有某些有趣的语义差异。 - noseratio - open to work