JavaScript中如何从Promise调用收集结果?解决数组未填充问题
问题原因
你遇到的问题是异步操作的时序问题:jobs.forEach里的fetch是异步任务,当你执行console.log(successful)时,所有请求还没完成,所以数组是空的。
解决方案
我们可以用Promise.all等待所有job请求完成,再处理结果并排序,下面是两种实现方式:
方式一:使用async/await(更易读)
async function foo() { const url = `https://foobar.com`; // 获取jobs列表 const response = await fetch(url, { method: 'POST', headers: headers }); const data = await response.json(); const jobs = data['jobs']; // 收集所有job请求的Promise const jobPromises = jobs.map(async (job) => { const jobUrl = job['url']; const jobResponse = await fetch(jobUrl, { headers: headers }); const jobData = await jobResponse.json(); // 只返回成功的任务数据 if (jobData['status'] === 'SUCCESS') { return { jobUrl, timeStamp: jobData['timestamp'] }; } return null; // 失败的任务返回null,后续过滤 }); // 等待所有请求完成,过滤null值得到成功的任务数组 let successful = (await Promise.all(jobPromises)).filter(item => item !== null); // 基于timestamp排序(如果timestamp是字符串,需要转成Date或数字,这里假设是时间戳数字) successful.sort((a, b) => a.timeStamp - b.timeStamp); console.log(successful); } foo();
方式二:使用Promise链(保持原风格)
function foo() { const url = `https://foobar.com`; fetch(url, { method: 'POST', headers: headers }).then(response => response.json()) .then(data => data['jobs']) .then(jobs => { // 用map生成所有请求的Promise数组 const jobPromises = jobs.map(job => { const jobUrl = job['url']; return fetch(jobUrl, { headers: headers }) .then(response => response.json()) .then(jobData => { if (jobData['status'] === 'SUCCESS') { return { jobUrl, timeStamp: jobData['timestamp'] }; } return null; }); }); // 等待所有请求完成后处理 return Promise.all(jobPromises); }) .then(results => { // 过滤失败的任务,得到成功数组 let successful = results.filter(item => item !== null); // 排序 successful.sort((a, b) => a.timeStamp - b.timeStamp); console.log(successful); }) .catch(err => console.error('请求出错:', err)); // 别忘了加错误捕获 } foo();
关键说明
Promise.all会等待所有传入的Promise都完成,才会返回结果数组,这样就能保证我们拿到所有请求的结果后再处理successful数组。- 排序时,如果你的
timestamp是ISO字符串(比如"2024-05-20T12:00:00Z"),可以把排序逻辑改成:new Date(a.timeStamp) - new Date(b.timeStamp)。 - 建议加上错误捕获(
.catch或try/catch),避免某个请求失败导致整个流程中断。
内容的提问来源于stack exchange,提问作者poly_glot
相关产品推荐
相关产品推荐

