【问题标题】:NodeJS - FOREACH function does not run all of elements and stopNodeJS - FOREACH 函数不会运行所有元素并停止
【发布时间】:2019-01-17 21:45:33
【问题描述】:

我在我的 mlab 数据库中存储了 2775 个 URL,然后我将每个 URL 删除以获取更多信息。我存储在一个数组中的所有 URL 然后将其传递给一个函数来处理。但是,代码最多只能运行大约 1700 个 url 并处理它然后停止。这是我的代码(对不起,这是我第一次使用stackoverflow:

Product.find({}, (err, foundProducts) => {
  if (err) {
    console.log("err " + err);
  } else {
    foundProducts.forEach(function(foundProduct) {
      var updateProduct = service.updateTikiProduct(foundProduct.url);
    });
  }
});

updateTikiProduct: function(url) {
    const options = {
        url: url,
        json: true
    };
    request(options,
            function(err, res, body) {
                // SOME code to crawl data

                Product.findOneAndUpdate({
                    url: options.url
                }, {
                    $set: {
                        name: name,
                        brand: brand,
                        store: store,
                        location: location,
                        base_category: categoryType,
                        top_description: topDescription,
                        feature_description: featureDescription
                    }
                }, {
                    upsert: true,
                    new: true
                }, (err, createdProduct) => {
                    if (err) {
                        reject(err);
                    } else {
                        var currentDate = new Date();

                        if (!createdProduct.hasOwnProperty("price")) {
                            createdProduct.price.push({
                                current: currentPrice,
                                origin: originPrice
                            });
                            createdProduct.save();
                        } else if (createdProduct.hasOwnProperty("price") &&
                            createdProduct.price[0].date.getDate() != currentDate.getDate()) {
                            createdProduct.price.push({
                                current: currentPrice,
                                origin: originPrice
                            });
                            createdProduct.save();
                            console.log("Update price");
                        }
                        counter++;
                        console.log("url : " + options.url);
                        console.log("Created product " + counter + " success!");
                    }
                });
            }

【问题讨论】:

  • 代码停止时控制台是否有错误?
  • 不行,代码运行的时候,我的内存快满了(大约90%~95%)。但是当它达到大约 1700 url 时,内存正常返回并且控制台停止运行。但是,控制台并没有告诉我它停止工作

标签: javascript node.js


【解决方案1】:

我猜 mongo 从 db 获取项目有限制,你应该尝试 findAll 或 https://stackoverflow.com/a/3705615/4187058

【讨论】:

  • 但是包含 2775 个 url 的集合非常少。您可以轻松地在 find() 中获取包含数千个文档的集合。您提供的链接是关于在 mongodb shell 中显示项目的限制
  • 好吧,你能看看foundProducts.length我不知道如何在mongo中升级有限数量的退货但我相信你应该看看它,或者也许在你的 forEach 抛出了一些异常,在那里使用 try/catch 来避免这种情况
  • 我试图打印出 foundProducts 的长度,它准确地返回了数字“2775”。感谢您的支持
【解决方案2】:

我认为您的代码没有处理所有元素是因为您正在并行处理所有元素,这将在内存满时停止处理。

foundProducts.forEach(function(foundProduct) {
    var updateProduct = service.updateTikiProduct(foundProduct.url);

});

您应该做的是按顺序处理它们。您可以为此使用 async await,进行以下更改即可:-

for(let foundProduct of foundProducts){
    var updateProduct = await 
        service.updateTikiProduct(foundProduct.url);
  };

【讨论】:

  • 感谢您的支持,但我之前尝试过,它也无法串联。我用“foreach”函数搜索了关于 async/await 的东西,他们告诉我它不能以正常方式工作。
  • 您可以使用 for..of 代替 foreach 它适用于异步等待。我已经更新了答案。如果它也不是串联工作,它会抛出任何错误吗?添加try...catch 块,看看是什么错误。
  • 但是如何在不初始化“async”的情况下运行“await”:v
  • 显然,如果没有异步,它将无法工作,您必须在函数 Product.find({}, async (err, foundProducts) => { 中添加 async
  • 我按照你说的试过了,但没有任何变化。但是,我认为问题在于您所说的,代码是并行运行的,但是我不知道为什么当我的代码仍在运行时,node.js 需要一些网络运行(大约 1MB~2MB),并且网络突然下降到 0 Mbps,它不再工作了
猜你喜欢
  • 2021-01-13
  • 1970-01-01
  • 2019-08-09
  • 2018-12-16
  • 1970-01-01
  • 2014-09-17
  • 1970-01-01
  • 2015-10-02
  • 2016-03-29
相关资源
最近更新 更多