Reputation: 307
I'm trying to executes two functions async series with node.JS. But I don't understand to do this.
Now, I have:
function 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);
}
function 2:
function range(client_id, callback) {
//Sort my array
callback(null, results);
}
And I call this functions here:
async.series([
search(client_id),
range(client_id);
], function (err, result) {
console.log(err);
console.log(result);
});
My problem: Second function is execute before the first because the first take more time. I need the result to first function to range my array with the function 2.
Upvotes: 1
Views: 1258
Reputation: 5162
If you aren't going to use results of the first function inside the second one directly (only via redis) you can use something like this:
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
});
Upvotes: 1
Reputation: 18197
You should use async.waterfall
instead of async.series
to get first function result in second function.
Runs the tasks array of functions in series, each passing their results to the next in the array. However, if any of the tasks pass an error to their own callback, the next function is not executed, and the main callback is immediately called with the error.
And, you have a big mistakes in your code. If I understand your code, you want go to the second function after modify all your results and return this for the second function right ? In this case, use async.each
instead of result.forEach
and call the callback after the 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);
});
});
}
Upvotes: 0
Reputation: 198294
search(client_id)
and range(client_id)
will execute immediately, have callback
argument assigned to undefined
then async.series
will try to execute the results of those functions as a series, and probably fail because those aren't functions, but undefined
. Or rather, it would, if the functions didn't try to do undefined(null, results)
.
Keep in mind, if f
is a function, f(...)
executes it. You need to pass functions themselves to async.series
, not results of their execution.
async.series
wants you to pass in an array or object of tasks, each task being function(callback) { ... }
.
Thus, the following should help:
async.series([
function(callback) { search(client_id, callback); },
function(callback) { range(client_id, callback); }
]...)
If you were writing in Haskell, that supports currying, your code would have been correct; but in JavaScript, f(x)(y)
is not the same thing as f(x, y)
.
You also don't call callback
from inside the Redis success function, which will also mess up your timing.
Upvotes: 0