执行async系列函数



我试图执行两个函数异步系列与node.JS。但是我不明白为什么要这样做。

现在,我有:

功能1:

function search(client_id, callback) {
    clientRedis.keys('director:*', function (err, results) {
        results.forEach(function (key) {
            clientRedis.hgetall(key, function (err, obj) {
                //SAVE RESULT
                console.log('save');
            });
        });
    });
    callback(null, results);
}

功能2:

function range(client_id, callback) {
    //Sort my array
    callback(null, results);
}

我在这里调用函数:

async.series([
    search(client_id),
    range(client_id);
], function (err, result) {
    console.log(err);
    console.log(result);
});

我的问题:第二个函数在第一个函数之前执行,因为第一个函数花费更多的时间。

我需要第一个函数的结果来使用函数2对数组进行范围划分。

如果你不打算在第二个函数中直接使用第一个函数的结果(仅通过redis),你可以使用这样的东西:

async.series([
    search.bind(null, client_id),
    range.bind(null, client_id)
], function (err, results) {
    console.log(err);
    console.log(results[0]); // for search results
    console.log(results[1]); // for range results
});

search(client_id)range(client_id)将立即执行,将callback参数分配给undefined,然后async.series将尝试执行这些函数的结果作为一个系列,并且可能失败,因为这些不是函数,而是undefined。或者更确切地说,如果函数不尝试执行undefined(null, results) .

请记住,如果f是一个函数,f(...)执行它。你需要将函数本身传递给async.series,而不是它们的执行结果。

async.series希望你传入一个任务数组或对象,每个任务都是function(callback) { ... }

因此,下面的代码应该有帮助:

async.series([
     function(callback) { search(client_id, callback); },
     function(callback) { range(client_id, callback); }
]...)

如果你是用Haskell写的,它支持curry,你的代码应该是正确的;但是在JavaScript中,f(x)(y)f(x, y)是不一样的。

你也不要从Redis success函数内部调用callback,这也会打乱你的计时。

您应该使用async.waterfall而不是async.series来获得第二个函数的第一个函数结果

按序列运行任务函数数组,每个函数将其结果传递给数组中的下一个函数。但是,如果任何任务将错误传递给它们自己的回调函数,则下一个函数不会执行,并且会立即调用主回调函数并伴有错误。

并且,你的代码中有一个大错误。如果我理解你的代码,你想去第二个函数后修改所有的结果,并返回这个为第二个函数,对吗?在这种情况下,使用async.each而不是result.forEach,并在async each之后调用回调:

function search(client_id, callback) {
    clientRedis.keys('director:*', function (err, results) {
        var savedElems = [];
        async.each(results, function (key, done) {
            clientRedis.hgetall(key, function (err, obj) {
                if (err) {
                    return done(err);
                }
                savedElems.push(obj);
                done();
            });
        }, function (err) {
            if (err) {
                return callback(err);
            }
            callback(null, savedElems);
        });
    });
}

最新更新