Javascript 执行异步系列的函数

Javascript 执行异步系列的函数,javascript,node.js,series,Javascript,Node.js,Series,我正在尝试使用node.JS执行两个函数async series。 但我不明白该怎么做 现在,我有: 职能1: function search(client_id, callback) { clientRedis.keys('director:*', function (err, results) { results.forEach(function (key) { clientRedis.hgetall(key, function (err, o

我正在尝试使用node.JS执行两个函数async series。 但我不明白该怎么做

现在,我有:

职能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的范围。

搜索(客户机id)
范围(客户机id)
将立即执行,将
回调
参数指定给
未定义
,然后
异步.series
将尝试将这些函数的结果作为一个序列执行,并且可能会失败,因为这些不是函数,而是未定义的。或者更确切地说,如果函数不尝试执行
未定义(null,results)

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

async.series
希望您传入一个数组或任务对象,每个任务都是
函数(回调){…}

因此,以下方面应该有所帮助:

async.series([
     function(callback) { search(client_id, callback); },
     function(callback) { range(client_id, callback); }
]...)
如果您使用支持咖喱的Haskell编写代码,那么您的代码应该是正确的;但是在JavaScript中,
f(x)(y)
f(x,y)
不是一回事


您也不能从Redis success函数内部调用
回调
,这也会打乱您的计时。

您应该使用
异步瀑布
而不是
异步系列
来获得第二个函数中的第一个函数结果

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

而且,您的代码中有一个很大的错误。如果我理解您的代码,您希望在修改所有结果后转到第二个函数并将其返回给第二个函数,对吗?在这种情况下,使用
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);
        });
    });
}

如果您不打算直接(仅通过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
});

另一方面,您是否知道在生产中不建议使用
redis.keys
,因为它会扫描所有的键?那么,我可以使用什么呢?您不会喜欢答案的:这取决于。你在那里买什么?一些对象ID?数据?范围数据、集合、序列化对象?我使用hmset命令创建一个列表。我有以下格式:{ID,'纬度',数字,“经度”,数字}。我想按距离排列这个列表中的所有ID,但我不能在列表hmset上设置“范围”,所以我使用一个带有ZADDPlease的数组,什么是bind?读取