Reputation: 133
everyone.
I have a problem about the 'callback function - scope of variable',
I wanna use the 'i in for loop' to 'the callback function User_UidSearch',
but I cannot use it.
(I hope the solution don't use the global variable.)
Task_TidSearchExecution = function(tid, callback) {
var sql = "SELECT * FROM execution WHERE task = '" + tid + "'";
dbclient.query(sql, function (err, results) {
if (err || results.length <= 0)
callback(false);
else {
console.log(results.length);
for (var i = 0 ; i < results.length ; i++) {
User_UidSearch(results[i].employee, function (user) {
console.log(i);
// results[i]['email'] = user.email;
});
}
callback(results);
}
});
}
the "console.log(i);"
Recheck, this is wrong. -> Outputs are "undefined" of all.
undefined is "console.log(result[i]);"
But the "i" is keep '2' console twice, if results.length is 2.
I know becuz the for loop ending then execute the User_UidSearch,
but how can I slove the it "i" is 0 and 1.
Upvotes: 2
Views: 9089
Reputation: 9447
Your problem may be solved, but let me still add these points so others know the correct approach.
Firstly, its not a good practice to call an asynchronous function inside a loop. This would lead to unexpected results.
Using closures is fine for some cases, but not this one. Read here for Practical uses of closures.
There are several problems in the approach you've taken,
callback(results)
will be called before even a single callback of User_UidSearch
is called.In your case, you should be using recursive function like this:
var len = results.length;
var count = 0;
function my_func() {
User_UidSearch(results[count].employee, function (user) {
console.log(count);
// results[count]['email'] = user.email;
count += 1;
if (count < len) {
my_func();
} else {
callback(results);
}
});
}
Read this if interested detailed explaination of different control flows.
Upvotes: 3
Reputation: 8110
You're dealing with closures, rewrite your code as follows:
...
(function(id) {
User_UidSearch(results[id].employee, function (user) {
console.log(id);
// results[i]['email'] = user.email;
});
})(i);
I.e. wrap your function to unbind i
.
Upvotes: 1