JS使用await处理Promise未按预期resolve的原因及规则咨询
问题结论
该现象是完全符合ECMAScript标准的预期行为,核心是对await关键字的作用逻辑理解偏差导致的。
底层逻辑说明
先明确两个核心规则:
returnPromise()函数的返回值永远是Promise实例对象,和是否加await无关await的作用是暂停async函数执行,等待后续Promise状态变更为已敲定(settled),如果是成功状态(fulfilled),await表达式本身会返回该Promise的resolve值,不会修改原始的Promise实例本身
两段代码的差异分析
第一段代码
function returnPromise() { return new Promise(resolve => { setTimeout(() => { resolve('result of promise'); }, 1000); }); } async function sth() { let result = await returnPromise(); console.log('result: ', result); console.log('flag 1'); } sth();
这里赋值给result的是await表达式的返回值,也就是Promise resolve后的值result of promise,所以打印得到预期的字符串。
第二段代码
function returnPromise() { return new Promise(resolve => { setTimeout(() => { resolve('result of promise'); }, 1000); }); } async function sth2() { let result = returnPromise(); // result被赋值为returnPromise返回的Promise实例 await result; // 仅等待Promise状态变为fulfilled,没有接收await的返回值,result仍然是原来的Promise实例 console.log('result: ', result); // 打印的是Promise实例对象,不是resolve的结果 console.log('flag 1'); } sth2();
你观察到打印结果是{}属于不同运行环境对Promise实例的打印展示差异,此时该Promise已经是fulfilled状态,并非pending。你可以通过两种方式验证:
- 追加代码
result.then(val => console.log(val)),会正常打印出result of promise - 将
await result修改为result = await result,就能拿到resolve的值,和第一段代码效果一致
问题原因
你之前的认知偏差在于误以为await会把后面的Promise变量直接修改为resolve值,实际上await只是等待Promise完成,本身返回resolve结果,不会修改原Promise变量的值。
内容的提问来源于stack exchange,提问作者Heon Yim
相关产品推荐
相关产品推荐

