在 forEach 循环中等待 promise

Posted

技术标签:

【中文标题】在 forEach 循环中等待 promise【英文标题】:Wait for promise in a forEach loop 【发布时间】:2018-02-12 02:42:32 【问题描述】:

我收到了来自数据库的书籍列表作为 Promise。

如果成功加载了初始书籍列表,则会通过将书籍传递给实用程序函数来进一步处理这些书籍。

实用程序函数内部是一个 forEach 循环,该循环遍历每本初始书籍,进行异步调用以获取其他信息,创建新书籍对象并将其添加到新书籍数组中(称为 updatedBooks)。

问题:我不知道如何等待每本书的 forEach 循环完成,以及如何返回新书数组。

目前,我只得到一本更新的书,而不是全部

我的最终目标是在 res.json() 对象中拥有更新书籍的列表

这是我目前的结构

controller.find(req.query)
    .then(function (entities) 
        awsUtil.addInfo(entities)
            .then(function (updatedBooks) 
                res.json(
                    confirmation: "success",
                    result: updatedBooks
                )
            )
            .catch(function (err) 
                res.json(
                    confirmation: "fail",
                    message: err
                )
            )
    )
    .catch(function (err) 
        res.json(
            confirmation: "fail",
            message: err
        )
    )

从 MongoDB 获取初始书籍的功能

find: function (params) 
    return new Promise(function (resolve, reject) 
        Book.find(params, function (err, books) 
            if (err) 
                reject(err)
                return
            

            console.log("Org. Books List: ", books)
            resolve(books);
        )
    )

获取附加信息并返回新书籍数组的实用函数

addInfo: function (books) 
    return new Promise(function (resolve, reject) 
        let updatedBooks = [];

        books.forEach(function (book) 
            client.itemLookup( //Call Amazon API to get book info
                idType: 'ISBN',
                itemId: book.isbn,
                responseGroup: 'ItemAttributes,Images'
            )
                .then(function (results) 
                    const updatedBook = 
                        // The additional info from result gets added here
                    

                    updatedBooks.push(updatedBook);
                ).catch(function (err) 
                console.log(err);
                reject(err)
            );
        )
        resolve(updatedBooks) //Return the array of new books
    )

【问题讨论】:

【参考方案1】:

修改addInfo 方法,使其将promise 存储在一个数组中,并返回Promise.all,这将在所有promise 都解决后解决。

假设你的方法返回了一个承诺,而且看起来确实如此,类似于

addInfo: function(books) 
  let promises = books.map(function(book) 
    return client.itemLookup(
      idType        : 'ISBN',
      itemId        : book.isbn,
      responseGroup : 'ItemAttributes,Images'
    ).then(function(results) 
      return 
        // The additional info from result gets added here
      
    );
  )
  return Promise.all(promises); // catch errors where you call "addInfo"

【讨论】:

你能帮我***.com/questions/48683679/…

以上是关于在 forEach 循环中等待 promise的主要内容,如果未能解决你的问题,请参考以下文章

ForEach 循环中的异步/等待节点 Postgres 查询

等待 forEach 循环

如何等待来自 forEach 循环的多个异步调用?

等待内部带有承诺的 forEach 完成

Node.js 等待循环中读取的所有文件

Node.js 等待循环中读取的所有文件