明显的区别:Promise 拒绝在不同的地方处理
-
return somePromise 会将 somePromise 传递给呼叫站点,await somePromise 将在呼叫站点结算(如果有的话)。因此,如果 somePromise 被拒绝,它不会被本地的 catch 块处理,而是由调用站点的 catch 块处理。
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');
}
})();
// 'OUT'
-
return await somePromise 将首先等待 somePromise 在本地定居。因此,值或异常将首先在本地处理。 => 如果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');
}
})();
// 'IN'
原因:return await Promise 在本地和外部等待,return Promise 只在外部等待
详细步骤:
返回承诺
async function delay1Second() {
return delay(1000);
}
- 致电
delay1Second();
const result = await delay1Second();
- 在
delay1Second() 内部,函数delay(1000) 立即返回一个带有[[PromiseStatus]]: 'pending 的promise。我们就叫它delayPromise吧。
async function delay1Second() {
return delayPromise;
// delayPromise.[[PromiseStatus]]: 'pending'
// delayPromise.[[PromiseValue]]: undefined
}
- 异步函数会将其返回值包装在
Promise.resolve()(Source) 中。因为delay1Second 是一个异步函数,所以我们有:
const result = await Promise.resolve(delayPromise);
// delayPromise.[[PromiseStatus]]: 'pending'
// delayPromise.[[PromiseValue]]: undefined
-
Promise.resolve(delayPromise) 返回delayPromise 没有做任何事情,因为输入已经是一个承诺(见MDN Promise.resolve):
const result = await delayPromise;
// delayPromise.[[PromiseStatus]]: 'pending'
// delayPromise.[[PromiseValue]]: undefined
-
await 等到 delayPromise 解决。
- 如果
delayPromise 满足 PromiseValue=1:
const result = 1;
- ELSE is
delayPromise 被拒绝:
// jump to catch block if there is any
返回等待承诺
async function delay1Second() {
return await delay(1000);
}
- 致电
delay1Second();
const result = await delay1Second();
- 在
delay1Second() 内部,函数delay(1000) 立即返回一个带有[[PromiseStatus]]: 'pending 的promise。我们称之为delayPromise。
async function delay1Second() {
return await delayPromise;
// delayPromise.[[PromiseStatus]]: 'pending'
// delayPromise.[[PromiseValue]]: undefined
}
- 本地等待将等到
delayPromise 得到解决。
-
案例 1:
delayPromise 满足 PromiseValue=1:
async function delay1Second() {
return 1;
}
const result = await Promise.resolve(1); // let's call it "newPromise"
const result = await newPromise;
// newPromise.[[PromiseStatus]]: 'resolved'
// newPromise.[[PromiseValue]]: 1
const result = 1;
// jump to catch block inside `delay1Second` if there is any
// let's say a value -1 is returned in the end
const result = await Promise.resolve(-1); // call it newPromise
const result = await newPromise;
// newPromise.[[PromiseStatus]]: 'resolved'
// newPromise.[[PromiseValue]]: -1
const result = -1;
词汇表:
- 解决:
Promise.[[PromiseStatus]] 从 pending 更改为 resolved 或 rejected