繁体   English   中英

承诺无法通过异步解决

[英]Promise not get resolved with async

我正在使用igmur api上传图像。 我使用Promises(异步等待)在Node.js中编写了一个应用程序。 (请注意,我对这些概念还很陌生)。

我的代码似乎确实有效。 它将图像上传到igmur。 但是,问题是,诺言没有得到解决。 请参考下面的代码。

router.post('/images/upload', async (req, res) => {
    /* we would receive a request of file paths as array */
    let filePaths = req.body.urls;

    let multipleUpload = new Promise(async (resolve, reject) => {
            let upload_len = filePaths.length,
                upload_res = new Array();

            for (let i = 0; i <= upload_len + 1; i++) {
                let filePath = filePaths[i];
                await imgur.upload(filePath, (error, result) => {
                    console.log(" A -> ");
                    if (upload_res.length === upload_len) {
                        console.log("******");
                        /* resolve promise after upload is complete */
                        resolve(upload_res)
                    } else if (result) {
                        /*push public_ids in an array */
                        console.log("OK")
                        upload_res.push(result.public_id);
                    } else if (error) {
                        console.log(error)
                        reject(error)
                    }

                })

            }
        })
        .then((result) => console.log(result))
        .catch((error) => error)

    let upload = await multipleUpload;
    res.json({
        'response': upload
    })
})

我遵循了本教程 ,该教程做了类似的事情。

我至少看到两个问题:

  • 您在不需要时将异步与承诺混合在一起
  • 我怀疑imgur.upload没有返回Promise,因为它接受了回调函数。

我认为这应该解决它:

router.post('/images/upload', async (req, res) => {
  let filePaths = req.body.urls
  let upload_len = filePaths.length
  let multipleUpload = filePaths.map(filePath => {
    return new Promise((resolve, reject) => {
      imgur.upload(filePath, (err, result) => {
        if (err) {
          reject(err)
        } else {
          resolve(result.public_id)
        }
      })
    })
  })

  let upload = await Promise.all(multipleUpload)

  res.json({
    response: upload,
  })
})

一个(非常)更高效的代码版本是:

function uploadToImgur(filePath) {
    return new Promise((resolve, reject) => {
        imgur.upload(filePath, (err, res) => {
            if (err) reject(err);
            resolve(res.public_id);
        })
    })

}

router.post('/images/upload', async (req, res) => {
    /* we would receive a request of file paths as array */
    let filePaths = req.body.urls;
    let promises = filePaths.map(uploadToImgur);
    let upload = await Promise.all(promises);
    res.json({
        'response': upload
    })
})

这使用Array.map创建一个诺言数组,一个诺言对应于每个filePath ,然后使用Promise.all同时等待所有诺言。

修正逻辑,以便在推送result后检查length 你从不叫resolve

例如,如果收到1个文件,则将推入数组,然后退出循环。

if (result) {
  /*push public_ids in an array */
  console.log("OK")
  upload_res.push(result.public_id);

  if (upload_res.length === upload_len) {
    console.log("******");
    /* resolve promise after upload is complete */
    resolve(upload_res)
  }
}

在另一个主题上,您应该在发生错误后退出循环,否则您可能最终会调用拒绝,然后解决,这不好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM