I am trying to create what I think is referred to as a "Waterfall". I want to sequentially process an array of async functions (jQuery promises).
Here's a contrived example:
function doTask(taskNum){ var dfd = $.Deferred(), time = Math.floor(Math.random()*3000); setTimeout(function(){ console.log(taskNum); dfd.resolve(); },time) return dfd.promise(); } var tasks = [1,2,3]; for (var i = 0; i < tasks.length; i++){ doTask(tasks[i]); } console.log("all done");
I would like it to complete the task in the order they are executed (present in the array). So, in this example I want it to do task 1 and wait for it to resolve then do task 2 wait for it to resolve, do task 3 etc and the log "all done".
Maybe this is really obvious but I've been trying to figure this out all afternoon.
A promise is used to handle the asynchronous result of an operation. JavaScript is designed to not wait for an asynchronous block of code to completely execute before other synchronous parts of the code can run. With Promises, we can defer the execution of a code block until an async request is completed.
To use Javascript promises in a for loop, use async / await . This waits for each promiseAction to complete before continuing to the next iteration in the loop. In this guide, you learn how async/await works and how it solves the problem of using promises in for loops.
A promise represents a value that is not yet known. This can better be understood as a proxy for a value not necessarily known when the promise is created. A deferred represents work that is not yet finished. A deferred (which generally extends Promise) can resolve itself, while a promise might not be able to do so.
If you are creating a Deferred, keep a reference to the Deferred so that it can be resolved or rejected at some point. Return only the Promise object via deferred. promise() so other code can register callbacks or inspect the current state. For more information, see the documentation for Deferred object.
I'd try using $().queue
instead of $.Deferred
here. Add the functions to a queue, and only call the next one when ready.
function doTask(taskNum, next){ var time = Math.floor(Math.random()*3000); setTimeout(function(){ console.log(taskNum); next(); },time) } function createTask(taskNum){ return function(next){ doTask(taskNum, next); } } var tasks = [1,2,3]; for (var i = 0; i < tasks.length; i++){ $(document).queue('tasks', createTask(tasks[i])); } $(document).queue('tasks', function(){ console.log("all done"); }); $(document).dequeue('tasks');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With