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');
});
});
}