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);
    
   ...