Márcio Paiva
Márcio Paiva

Reputation: 1003

Dealing with asynchronous function

I have just started programming with JS and Node, and I haven't got used to asynchronous stuff yet. Basically, i have the following code:

for (var i=0, len=sources.length; i<len; i++) {
    processSource(sources[i], function(info) {
        doesOtherStuff(sources[i], info);
    });
}

It doesn't really work, because, as processSource takes a while to finish, the function doesOtherStuff is called with unmatching arguments, like sources[2] and the processed info for sources[0].

What is the correct way of dealing with this? Is there something inherently wrong with the design of these functions. (both processSource and doesOtherStuff are my functions).

Upvotes: 1

Views: 90

Answers (4)

damphat
damphat

Reputation: 18966

javascript style could help you:

sources.forEach(function (e) {
    processSource(e, function(info) {
        doesOtherStuff(e, info);
    });
}

Upvotes: 1

Max Truxa
Max Truxa

Reputation: 3478

1) Use var instead of int.

2) You have a superfluous ) in your call to processSource.

processSource(sources[i], function(info) /* No 2nd ')' here */ {
    doesOtherStuff(sources[i], info);
});

should work.

Upvotes: 0

Clarence Leung
Clarence Leung

Reputation: 2566

Try using Caolan's async library - this works on Node and in the browser. You can then do something like this:

async.map(sources, function (item, callback) {
    // Do your actions on each item here
    processSource(item, function (info) {
        var result = doOtherStuff(item, info);

        // Send callback so the next item can be processed
        callback(null, result);
    });
}, function (err, results) {
   // Handle the processed results here
});

Upvotes: 0

epascarello
epascarello

Reputation: 207557

The problem with the code is the fact that i is not want you expect it to be.

When the loop completes, the function-level variable i has the value of sources.length. So when doesOtherStuff runs that is what the inner function uses.

for (var i=0, len=sources.length; i<len; i++) {
    (function(i) {
        processSource(sources[i], function(info) {
            doesOtherStuff(sources[i], info);
        });
    })(i);
}

Upvotes: 2

Related Questions