首页 > 解决方案 > JavaScript 并行调用多个异步调用

问题描述

我有一个名为imagesToUpload. 上传函数返回一个承诺。现在只好等着,一张张上传图片。这是我的示例代码。

function uploadTos3Bucket(filename){
    return new Promise((resolve,reject)=>{
        resolve(filename+'.png')
    })
}

const imagesToUpload = ['Homer','Bart','Lisa','Millhouse'];

async function controller() {
    const links = []

    for (const imageFile of imagesToUpload) {
        const link = await uploadTos3Bucket(imageFile);
        links.push(link)
    }
    console.log('links',links)
    
}
controller();

而不是这个,我想要传递图像数组的东西。图片并行上传。全部完成后,我得到链接数组。因为我知道这个概念Promise.all()

这不是我想要的。

const [image1,image2] = await Promise.all([uploadTos3Bucket('Homer'),uploadTos3Bucket('Bart')])

我不想分配给这么多变量。我只想要一个包含所有链接的数组,最重要的是,如果某些图像无法上传,它应该忽略而不是破坏整个过程。

标签: javascriptasync-await

解决方案


imagesToUpload数组中,使用.map将其转换为 Promises 数组,然后调用Promise.allSettled该数组,通过检查status每个结果对象的属性来过滤已实现的 Promise,最后过滤.map它们的解析值:

function uploadTos3Bucket(filename){
    return new Promise((resolve,reject)=>{
        resolve(filename+'.png')
    })
}

const imagesToUpload = ['Homer','Bart','Lisa','Millhouse'];

async function controller() {
  const results = await Promise.allSettled(imagesToUpload.map(uploadTos3Bucket));
  const links = results
    .filter(({ status }) => status === 'fulfilled')
    .map(({ value }) => value);
  console.log('links',links)  
}
controller();

对于尚未识别的浏览器Promise.allSettled,添加一个polyfill或使用此处列出的众多方法之一来实现该功能。


推荐阅读