异步使用节点中的循环等待承诺

apeeds0o  于 2021-09-23  发布在  Java
关注(0)|答案(1)|浏览(378)

在我开始之前,这完全是我没有完全理解node/javascript中异步编程的复杂性。
我有一个多维数组,包含图像URL和输出名称。我试图使用sharp对它们进行迭代、下载、操作和输出。我试图做的是捕获shape作为错误抛出的任何损坏图像,更新阵列,并在任务完成后继续处理阵列。
我遇到的问题是我的代码没有等待集成完成,因此没有继续更新阵列。
这就是我正在使用的代码类型:

let imgArr = [['url1', 'url2', 'url3', 'url4'],['name1', 'name2', 'name3', 'name4']]

function saveImg(url, output)
    return new Promise(async(resolve, reject) => {
       axios.get(url, { responseType: 'arraybuffer' })
       .then((res) => {
          sharp(res.data)
          .resize({changing size etc})
          .png({quality: 95})
          .toFile(output)
          .then(() => { resolve() })
          .catch((err) => { reject() })
    })
}

function processImg(obj){
   return new Promise(async(resolve, reject) => {
      for(let i = 0; i < obj.length; i++){
         saveImg(obj[i][0], obj[i][1])
         .catch((err) => {
             imgArr[i][1] = 'image-not-found.png'
         })
      }
      resolve()
   })
 }

async function doStuff(){
     processImg(imgArr)
        .then(() => {
            console.log(imgArr) // this is where I'd hoped the updated array would appear
        })
        .catch((err) => {
            console.log(err)
        })
)

doStuff()

谢谢

xiozqbni

xiozqbni1#

当你履行承诺时 for 这样循环,它们都是并行开始的。然后你打电话 resolve() 就在承诺真正解决之前。
你可以用 Promise.all (或 Promise.allSettled 正如@funkizer在评论中建议的那样)要解决此问题:

function processImg(obj){
   return new Promise(async(resolve, reject) => {
      Promise.allSettled(obj.map((item, i) =>
         saveImg(item[0], item[1])
         .catch((err) => {
             imgArr[i][1] = 'image-not-found.png'
         })
      )).then(resolve)
   })
 }

但是这个包裹 new Promise 没有必要;您可以直接退还承诺,如下所示:

function processImg(obj){
   return Promise.allSettled(obj.map((item, i) =>
      saveImg(item[0], item[1])
      .catch((err) => {
          imgArr[i][1] = 'image-not-found.png'
      })
   );
}

你可以同样地简化 saveImg :

function saveImg(url, output)
    return
       axios.get(url, { responseType: 'arraybuffer' })
       .then((res) =>
          sharp(res.data)
          .resize({changing size etc})
          .png({quality: 95})
          .toFile(output)
       );
}

相关问题