Nyxynyx Nyxynyx - 4 months ago 10
Javascript Question

setTimeout on Asynchronous function

I have a asynchronous function that I want to have a 5000ms delay before being fired. I am trying to use

setTimeout()
to achieve this. This async function occurs in a loop that runs several times, with the async function being passed different data each time, thus
setInterval()
cannot be used here.

Problem: The async function gets triggered instantly without delay (console prints 5
Done
messages instantly` and loops without any delay. What happened, and how can I solve it?

Javascript Code

someFunction(listings, function() {
for (var i in listings ) {
var listing = listings[i];
setTimeout(asyncFunction(listing, function(data) {
console.log('Done');
}), 5000);
}
});

Answer

You have to wrap the function in another function. Currently, you're invoking the function, and passing the return value as an argument to setTimeout. The code below will (correctly) pass a function to setTimeout. After 5 seconds, the function executes.

I had to add two functions to achieve the desired behaviour, because of scoping issues. After 5 seconds, the loop has already finished, and the listing variable would be equal to the last element in listings.

someFunction(listings, function() {
    var counter = 0;  // Define counter for 5 second-delays between each call
    for (var i in listings ) {
        var listing = listings[i];
        (function(listing){ //Closure function
            setTimeout(function(){ //setTimeout function
                // Because of the closure, `listing` is unique
                asyncFunction(listing, function(a, b) {
                    console.log('Done');
                });
            }, 5000 * ++counter); //Increase counter for each loop
        })(listing);
    }
});
Comments