JSFiddle - React, Tailwind, and code Playground

by cdaringe

HTML

<h1>The dangers of mixin' async Promise code without knowin' what you're up to...</h1>
<h4>Sometimes you want syncronous overall flow, however, you want to exploit some async goodness mixed in in the middle, then to converge again</h4>

<p>A strategy I like it to have your async calls:</p> <ol>
<li>Return a promise to an array along with the other async promises you're making (perhaps the async call on many data items)</li>
<li>build up the data that you need asyncronously</li>
<li>Include the rest of your syncronous code as a subroutine of Promise.all(YOUR_ARRAY_OF_ASYNC_PROMISES)</li>
</ol>
<p>Now your async calls have finished, you have a data object to play with, and can continue sync execution.  Toggle the two functions @the top of the js pane to see the difference.</p>

<div class="log">
    <h3>Log</h3>
<ul id="log"></ul>
</div>

CSS

.log{
    background-color:#FFEAB6;
    border-radius:5px;
    font-family:"Helvetica", Arial;
    padding: 10px;
}

JavaScript

IntendedToBeSync();  //watch us run a function with async calls in the middle
//IsSync(); //is sync, with some async guts


function post(txt){
    var newItem = document.createElement("li");
    newItem.innerHTML += txt;
    document.getElementById('log').appendChild(newItem);
}

function aSyncFubarIt(results){
    var response = '';
    if(!results) response = 'Did you expect me to finish inside the forEach!?  It\'s unlikely that I will!';
    else response = 'ah-ha! you passed in an array to build up.  Your promises shall fulfill, and you can use me!';
    return new Promise(function(resolve,reject){
        window.setTimeout(function(){
            if(results) results.push(response);
            resolve(response);
        },50);
    });
}

function IntendedToBeSync (){
    var data = [1,2,3];
    post('start IntendedToBeSync - la la la, synchronous code...');
    var p1 = new Promise(function(resolve, reject){
        post('  IntendedToBeSync - start promise');
        data.forEach(function(item,ndx,arry){
            post('   mid promise, forEach : ' + item);
            aSyncFubarIt().then(post);  //WHAT'S THIS LITTLE GUY?
        });
        post('  IntendedToBeSync - end promise');
    });
    post('end IntendedToBeSync');
    
}

function IsSync (){
    var data = [4,5,6],
        asyncResults = [];
    post('start IntendedToBeSync - la la la, synchronous code...');
    var p1 = new Promise(function(resolve, reject){
        post('IntendedToBeSync - start promise');
        var pdata = data.map(function(item,ndx,arry){
            post('   mid promise, forEach : ' + item);
            return aSyncFubarIt(asyncResults);  //WHAT'S THIS LITTLE GUY?
        });
        //all is done now
        Promise.all(pdata).then(function(){
            post('IntendedToBeSync - end promise');
            asyncResults.forEach(function(result){
                post(result);
            });
            post('end IntendedToBeSync');
        });
    });    
}