【问题标题】:Optional callback not being called in the node.js async module's forEachOf method在 node.js 异步模块的 forEachOf 方法中未调用可选回调
【发布时间】:2015-09-14 19:43:52
【问题描述】:

我正在使用异步模块的 forEachOf 方法在遍历对象后打印最终结果。这是我正在做的事情的简化版本:

var async = require('async'),
    cheerio = require('cheerio'),
    request = require('request');

var returnArray = [];

async.forEachOf(myObj, function (value, key, callback) {
    var anotherObj = {};

    anotherObj.type = "val1";

    request(someurl, function(err, res, body) {
        if (err) {
            return callback(err);
        }

        var $ = cheerio.load(body);

        anotherObj.name = "val2";

        var miniObj = {};
        $('#some-element', "#an-id").each(function(i, value) {
            var val = value.value;
            miniObj[size] = val;
        });

        anotherObj.miniObj = miniObj;

        returnArray.push(anotherObj);

        return callback();
    });
}, function (err) {
    if (err) {
        console.error(err.message);
    }

    console.log(returnArray);
});

但是,当我运行程序时,没有任何东西(即“returnArray”)被打印到控制台上。

作为参考,我查看了这些其他类似的帖子:

我不确定我在这里做错了什么。谁能指出我做错了什么?

谢谢!

编辑:所以我想我终于弄清楚我做错了什么。在我之前提供的另一个示例中 HERE, using Runnable 我忘记添加“return callback()”语句。然后它起作用了。该示例与此示例之间的唯一区别是我在上面提供的示例中的“return callback()”语句本身是在另一个异步方法中调用的。我认为为了解决我的问题,我必须以某种方式确保(可能使用异步库中的一些控制流函数)在第二个异步方法完成后在正确的“范围/级别”调用“返回回调()”。我想我会将此归因于我的错误,因为缺少关于在异步文档中正确使用“return callback()”语句的文档。一旦我弄明白了(并睡了一会儿),我会用解决方案更新这篇文章!

【问题讨论】:

  • returnObject vs returnArray?
  • 糟糕!那只是一个错字。
  • 你的 myObj 对象的结构是什么?您确定不应该使用“async.each”吗?
  • @LuisDelgado - 我之前将 myObj 打印到控制台,我绝对确定它采用 javascript 中典型对象的形式。我也知道 anotherObj 的构造是正确的,因为当我在 forEachOf 循环中为其添加日志语句时,我得到了我期望打印到控制台的内容。
  • @youngrrrr,好的,我明白了。作为个人说明,到目前为止,我还没有成功地使异步与本身具有内部回调异步函数的函数一起工作。对于这些情况,我使用了 async.waterfall 之类的东西。您的异步函数有一个使用请求的内部异步调用。您是否尝试过构建代码以使您的异步函数没有嵌套的异步调用?

标签: javascript node.js asynchronous callback async.js


【解决方案1】:

您的陈述:

if (err) {
    return callback(err);
}

对异步编程无效。相反,您应该这样做:

if(err) callback(err);

这就是您没有得到任何回报的原因。我用异步概念重写了你的代码:

var async = require('async'),
var cheerio = require('cheerio'),
var request = require('request');

var returnArray = [];
async.forEachOf(myObj, function (value, key, next) {
    var anotherObj = {};

    anotherObj.type = "val1";

    request(someurl, function(err, res, body) {
        if (err) next(err);

        var $ = cheerio.load(body);

        anotherObj.name = "val2";

        var miniObj = {};
        async.each($('#some-element', "#an-id"), function (value, next) {
          var val = value.value;
          miniObj[size] = val;
        });

        anotherObj.miniObj = miniObj;

        returnArray.push(anotherObj);

        next();
    });
}, function (err) {
    if (err) console.error(err.message);

    console.log(returnArray);
    callback(returnArray);

});

请注意,您有两个不同的命名回调。外部函数回调称为callback。内部函数回调称为next

【讨论】:

  • 这绝对是错误的。建议使用返回回调,以防回调不是您函数中的最后一条语句,在这种情况下您将收到“回调被调用两次”错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-10-04
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 2017-03-20
  • 2016-08-27
  • 2015-03-12
相关资源
最近更新 更多