为何Promise.all()与async函数配合无法得到预期结果?
问题分析与解决:Promise.all() 未按预期等待异步操作
原代码问题
先看你提供的原代码:
var p2 = 1337; var p3 = new Promise((resolve, reject) => { setTimeout(resolve, 2000, 'foo'); }); var apiCall = async () =>{ // 模拟5秒后响应的API调用 setTimeout(() => {return 1000}, 5000); } Promise.all([p2,p3,apiCall()]).then(values => { console.log(values); // 预期[1337, 'foo', 1000],实际得到[1337, 'foo', undefined] }); apiCall().then((response)=>{console.log(response)})
核心问题1:async函数未正确等待setTimeout
async函数确实会返回Promise,但如果函数内部没有显式返回值,就会返回一个已resolve的Promise,值为undefined。setTimeout是传统回调式异步API,不会返回Promise,async函数不会自动等待它执行完成。你的apiCall里,setTimeout的回调返回1000,但这个返回值完全不会传递到async函数外部,函数执行到setTimeout这一行后就直接结束,因此返回的Promise立刻resolve为undefined。
核心问题2:补充尝试的错误
你修改后的代码:
var apiCall = async () =>{ // 模拟5秒后响应的API调用 const a = setTimeout(() => {return 1000}, 5000); return a }
这里返回的a是setTimeout的定时器ID(一个数字),不是你想要的1000。setTimeout的回调里的return对外部没有任何影响,因为回调是在独立调用栈中执行的,和apiCall函数的返回值无关。
正确写法
要让apiCall返回一个5秒后resolve为1000的Promise,有两种常用方式:
方式1:用Promise构造函数包裹setTimeout
var apiCall = () => { return new Promise((resolve) => { setTimeout(() => { resolve(1000); }, 5000); }); };
方式2:async函数配合await(本质基于Promise)
// 简洁写法 var apiCall = async () => { await new Promise(resolve => setTimeout(resolve, 5000)); return 1000; };
修改后运行Promise.all([p2,p3,apiCall()]),会在5秒后输出[1337, 'foo', 1000],符合预期。
内容的提问来源于stack exchange,提问作者Ae Leung
相关产品推荐
相关产品推荐

