JSFiddle - React, Tailwind, and code Playground
by tchaffee
HTML
<h1>Asynchronous (should be more or less in reverse order):</h1>
<div id="outputAsync"></div>
<h1>Synchronous (should always be in correct order):</h1>
<div id="outputSync"></div>
JavaScript
// How to force async functions to execute sequentially
// by using deferred pipe chaining.
// The master deferred.
var dfd = $.Deferred(), // Master deferred
dfdNext = dfd; // Next deferred in the chain
x = 0, // Loop index
values = [], // Saves loop values because functions are called after loop finishes
// Outputs values, you don't need to understand this.
updateDom = function (el, val) {
$(el).append('<p>Value is: ' + val + '</p>');
},
// Simulates $.ajax, but with predictable behaviour.
// You only need to understand that higher 'value' param will finish earlier.
simulateAjax = function (value) {
var dfdAjax = $.Deferred();
console.log('simulateAjax with value: ' + value);
setTimeout(
function () {
console.log('simulateAjax DONE with value: ' + value);
dfdAjax.resolve(value);
},
1000 - (value * 100)
);
return dfdAjax.promise();
},
// This would be a user function that makes an ajax request
requestAjax = function (value) {
console.log('requestAjax with value: ' + value);
return simulateAjax(value);
};
// Normal async calls.
for (x = 1; x <= 4; x++) {
console.log('Normal async loop x = ' + x);
requestAjax(x).
done(function (response) {
console.log('Async requestAjax done ' + response);
updateDom('#outputAsync', response);
});
}
// Start the pipe chain. You should be able to do this anywhere in the program, even
// at the end,and it should still give the same results.
console.log('Setting off the pipes...');
dfd.resolve();
// Deferred pipe chaining.
// What you want to note here is that an new ajax call will not start until the previous
// ajax call is completely finished.
//
for (x = 5; x <= 8; x++) {
values.push(x);
console.log('Deferred pipe chaining x = ' + x);
...