每个循环中有多个猫鼬调用

时间:2019-05-24 14:02:04

标签: javascript node.js mongodb mongoose

我正在读取JSON对象并遍历每个项目。我首先要检查该项目是否已经存在于数据库中,如果存在,我想记录一条消息。如果尚不存在,我想添加它。

这正常工作,但是,我想添加一个回调或使用process.exit()完成该过程。

由于猫鼬调用是异步的,我无法将其放在for循环的末尾,因为它们尚未完成。

我应该如何处理此问题的最佳方法是什么?

function storeBeer(data) {
    data.forEach((beer) => {
        let beerModel = new Beer({
            beer_id: beer.id,
            name: beer.name,
            image_url: beer.image_url
        });
        Beer.findOne({
            'name': beer.name
        }).then(function (result) {
            if (result) {
                console.log(`Duplicate ${result.name}`)
            } else {
                beerModel.save(function (err, result) {
                    console.log(`Saved: ${result.name}`)
                });
            }
        });
    });
}

有什么我应该读的书来帮助解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

一种管理异步资源的方法是通过Promise对象,它们是Javascript中的一流对象。这意味着它们可以组织成数组,并且可以像其他任何对象一样进行操作。因此,假设您想像问题所暗示的那样并行存储这些啤酒,则可以执行以下操作:

function storeBeer(data) {
    // This creates an array of Promise objects, which can be
    // executed in parallel.
    const promises = data.map((beer) => {
        let beerModel = new Beer({
            beer_id: beer.id,
            name: beer.name,
            image_url: beer.image_url
        });

        return Beer.findOne({
              'name': beer.name
          }).then(function (result) {
              if (result) {
                  console.log(`Duplicate ${result.name}`)
              } else {
                  beerModel.save(function (err, result) {
                      console.log(`Saved: ${result.name}`)
                  });
              }
          });
        );
    });

    return Promise.all(promises);
}

请不要忘记storeBeer函数现在是异步的,将需要通过Promise链或async/await来使用。

例如,要在之后添加进程退出:

async function main() {
  const beers = [ ... ];
  await storeBeer(beer);
  process.exit(0);
}

您还可以修改以上示例,以在storeBeer块内调用try / catch函数,以根据抛出的任何错误以不同的错误代码退出。