We're going to set up a simple asynchronous scenario with setTimeout.
setTimeout accepts two arguments. The second argument is the amount of time to wait, and the first argument is a callback which will be evaluated when the time expires.
We're going to wrap setTimeout in a higher order function that will allow us to pass in an object to log, a success handler to evaluate in a happy case and an error handler to evaluate if something unexpected occurs.
//awesome utility library
const _ = require('lodash');
//simple logger
const logWaitObject = function (waitObject) {
console.log(waitObject.order + ' ' + waitObject.length);
}
//simple error handler
const notNumberError = function (waitObject) {
console.log('Not a number ' + waitObject.length);
}
//my fake asynchronous action
const doSomethingAsync = function (waitObject, handleAsyncSuccess, handleAsyncError) {
if(!_.isNumber(waitObject.length)) {
handleAsyncError(waitObject);
return;
}
setTimeout(function ( ) {
handleAsyncSuccess(waitObject);
}, waitObject.length);
};
//callback for success
const handleAsyncSuccess = function (waitObject) {
logWaitObject(waitObject);
};
//callback for error
const handleAsyncError = function (waitObject) {
notNumberError(waitObject);
};const waitObjects = [
{ order: 'First', length: 900 },
{ order: 'Second', length: '**no duh, idiot**' },
{ order: 'Third', length: 300 },
{ order: 'Fourth', length: 100 },
];
doSomethingAsync(waitObjects[0], handleAsyncSuccess, handleAsyncError);
doSomethingAsync(waitObjects[1], handleAsyncSuccess, handleAsyncError);
doSomethingAsync(waitObjects[2], handleAsyncSuccess, handleAsyncError);
doSomethingAsync(waitObjects[3], handleAsyncSuccess, handleAsyncError);
The output order is unpredictable, something like:
Not a number **no duh, idiot**
Fourth 100
Third 300
First 900
doSomethingAsync(waitObjects[0],
function (waitObject) {
logWaitObject(waitObject);
doSomethingAsync (waitObjects[1],
function (waitObject) {
logWaitObject(waitObject);
doSomethingAsync (waitObjects[2],
function (waitObject) {
logWaitObject(waitObject);
doSomethingAsync(waitObjects[3],
function (waitObject) {
notNumberError(waitObject);
},
function (waitObject) {
notNumberError(waitObject);
}
);
},
function (waitObject) {
notNumberError(waitObject);
}
);
},
function (waitObject) {
notNumberError(waitObject);
}
);
},
function (waitObject) {
notNumberError(waitObject);
}
);We're going to set up a simple asynchronous scenario with setTimeout.
setTimeout accepts two arguments. The second argument is the amount of time to wait, and the first argument is a callback which will be evaluated when the time expires.
We're going to wrap setTimeout in a higher order function that will allow us to pass in an object and return a promise.
const _ = require('lodash');
//simple logger
const logWaitObject = function (waitObject) {
console.log(waitObject.order + ' ' + waitObject.length);
}
//my fake asynchronous action
const doSomethingAsyncPromise = function (waitObject) {
const timeoutPromise = new Promise(function (resolve, reject) {
if (!_.isNumber(waitObject.length)) {
reject(waitObject);
}
setTimeout(resolve, waitObject.length, waitObject);
});
return timeoutPromise;
}
const waitObjects = [
{ order: 'First', length: 900 },
{ order: 'Second', length: '**no duh, idiot**' },
{ order: 'Third', length: 300 },
{ order: 'Fourth', length: 100 },
];
const promiseArray = [];
doSomethingAsyncPromise(waitObjects[0])
.then(function (waitObject) {
logWaitObject(waitObject);
return waitObject;
})
.then(function (waitObject) {
return doSomethingAsyncPromise(waitObject[1]);
})
.then(function (waitObject) {
logWaitObject(waitObject);
})
.catch(function (waitObject) {
console.log('not a number');
});
//Output Produces
First 900
not a numberWe had an issue where we needed to do several api requests to get daily account balances and then perform an action once they were all completed.
loadDailyAccountBalances (accounts, startDate, endDate) {
let dailyAccountBalances = [];
let requestCount = accounts.length;
accounts.forEach(account => {
const requestUrl = ApiEndpoints.ACCOUNTS + '/'
+ account.guid
+ '/daily_account_balances'
+ '/from/' + startDate + '/to/' + endDate;
request.get(requestUrl, {
success (res) {
requestCount -= 1;
dailyAccountBalances = dailyAccountBalances.concat(res.daily_account_balances);
if (requestCount <= 0) {
ServerActions.dailyAccountBalancesLoaded(dailyAccountBalances);
}
}
});
});
},loadDailyAccountBalances (accounts, startDate, endDate) {
let dailyAccountBalances = [];
const requests = [];
accounts.forEach(account => {
requests.push({
url: ApiEndpoints.ACCOUNTS + '/' + account.guid + '/daily_account_balances' + '/from/' + startDate + '/to/' + endDate
});
});
const fetches = FetchUtils.createFetchArray(requests);
Promise.all(fetches)
.then(jsonArray => {
jsonArray.forEach(json => {
dailyAccountBalances = dailyAccountBalances.concat(json.daily_account_balances);
});
ServerActions.dailyAccountBalancesLoaded(dailyAccountBalances);
})
.catch(error) => {
ServerActions.dailyAccountBalancesError(error.response.daily_account_balances, error);
});
}