SetTimeout for an asynchronous function

I have an asynchronous function with which I want to have a delay of 5000 ms before firing it. I am trying to use setTimeout() to achieve this. This asynchronous function is executed in a loop that is executed several times, while the asynchronization function passes different data each time, so setInterval() cannot be used here.

Problem: The async function starts instantly without delay (the 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); } }); 
+6
source share
4 answers

You must wrap the function in another function. You are currently calling this function and passing the return value as an argument to setTimeout . The code below (correctly) will pass the setTimeout function. After 5 seconds, the function performs.

I had to add two functions to achieve the desired behavior due to problems with the definition of the area. After 5 seconds, the loop is already completed, and the listing variable will 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); } }); 
+9
source

If you are using ECMAScript6 , you can use Promise .

So, create a delay function that ends the setTimeout call in Promise:

 function delay(ms) { return new Promise(function (resolve) { return setTimeout(resolve, ms); }); }; 

And you can use it like this:

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

If you are using ECMAScript 2017 , you can use aync / WAIT .

Async functions return a promise, so you do not need to change the delay function code.

 async someFunction(listings, function() { for (var i in listings ) { var listing = listings[i]; await delay(5000); await asyncFunction(listing); console.log('Done'); } }); 
+4
source

Not knowing what your asyncFunction , it would seem that it can simply return the function you passed to it.

 someFunction(listings, function() { for (var i = 0; i < listings.length; ++i ) { setTimeout(asyncFunction(listings[i], function(data) { console.log('Done'); }), 5000 * i); } }); function asyncFunction( lstng, func ) { return func; } 

Although I would expect that you would need to add additional logic.

 function asyncFunction( lstng, func ) { return function() { // do some stuff with the listing // then invoke the func func(); } } 

Now your asyncFunction wraps everything you need in a new function that returns in setTimeout . The new function also calls the callback you passed.


JSFIDDLE DEMO

+1
source

that is the difference. The key point is what asyncFunction do? can you paste it?

 var foo=function(){ alert("BAR"); return function(){ alert("I AM!"); }; } setTimeout(foo(),4000); setTimeout(foo,5000); 
-1
source

Source: https://habr.com/ru/post/902446/


All Articles