等待forEach循环中的promise [英] Wait for promise in a forEach loop

查看:392
本文介绍了等待forEach循环中的promise的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从数据库收到一份书籍列表作为承诺。

I am receiving a list of books from a database as a Promise.

如果成功加载了初始书籍列表,则通过传递书籍进一步处理书籍实用函数。

If the initial list of books is successfully loaded, the books are further processed by passing them to a utility function.

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

Inside the utility function is a forEach loop which loops over each initial book, makes an async call to get additional information, creates a new book object and adds it to an array of new books (called updatedBooks).

问题:我不知道如何等到forEach循环是完成了每本书,以及如何返回新书。

Problem: I don't know how to wait until the forEach loop is finished with every book and how to return the array of new books.

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

Currently, I only get one updated book instead of all

这个是我目前的结构

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
    })
}


推荐答案

修改 addInfo 方法,使其将promises存储在数组中,然后返回 Promise.all 相反,它将解决所有承诺已解决的问题。

Modify the addInfo method so it stores the promises in an array, and return Promise.all instead, which will resolve when all the promises have resolved.

假设您的方法返回一个承诺,它看起来像是这样的,比如

Assuming your methods returns a promise, and it looks like they do, something like

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"
}

这篇关于等待forEach循环中的promise的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆