Skip to content

Instantly share code, notes, and snippets.

@akirattii
Last active March 8, 2017 07:35
Show Gist options
  • Save akirattii/5c3136d32aafcbd678fe8b8712af5eda to your computer and use it in GitHub Desktop.
Save akirattii/5c3136d32aafcbd678fe8b8712af5eda to your computer and use it in GitHub Desktop.
How to execute async functions in order using pure js
// Executes async functions in order using pure js
/**
* Loop async func in order
* @param {Array} - array each object has below properties:
* - fn: {Function} - function to loop
* - param: {Object} - parameter to pass the function
* @param {Function} - error-first style callback returns below params as argument:
* - errs: array of error
* - results: array of result
*/
function stepAsyncFuncs(arr, cb) {
let i = 0;
let len = arr.length;
let counter = 0;
let errs = [];
let results = [];
if (!arr || arr.length <= 0)
return cb && cb(errs, results);
function _stepAsyncFuncs(arr, cb) {
let fn = arr[i]["fn"];
let param = arr[i]["param"];
setTimeout(function() {
fn(param, function(err, msg) {
// console.log("err:", err);
errs.push(err);
results.push(msg);
i += 1;
counter += 1;
if (counter >= len) {
return cb && cb(errs, results);
} else {
_stepAsyncFuncs(arr, cb);
}
});
}, 1);
}
// fire at first:
_stepAsyncFuncs(arr, cb);
}
// Any async function:
let asyncFn = function({
no,
time
}, cb) {
setTimeout(function() {
let msg = "I am no." + no;
console.log(msg);
return cb(null, msg);
}, time);
}
// Make step list:
let steps = [{
fn: asyncFn,
param: {
no: 0,
time: 2000
}
}, {
fn: asyncFn,
param: {
no: 1,
time: 100
}
}, {
fn: asyncFn,
param: {
no: 2,
time: 1000
}
}, {
fn: asyncFn,
param: {
no: 3,
time: 300
}
}];
// Executes all async functions in order following the step list:
stepAsyncFuncs(steps, function(errs, results) {
console.log("All execution has end!");
console.log(" errs:", errs);
console.log(" results:", results);
});
/* Console log:
I am no.0
I am no.1
I am no.2
I am no.3
All execution has end!
errs: [null, null, null, null]
results: ["I am no.0", "I am no.1", "I am no.2", "I am no.3"]
*/
// Executes async functions in order using pure js (uses Generator)
// Any async function:
let asyncFn = function(iter, {
no,
time
}, cb) {
// Unless use `setTimeout`, `Generator is already running` error occurs!
setTimeout(function() {
let msg = "I am no." + no;
console.log(msg);
cb(null, msg);
return iter.next();
}, time);
}
// // sleep
// function sleep(iter, ms) {
// setTimeout(function() {
// iter.next();
// }, ms);
// }
// Make step list:
let steps = [{
fn: asyncFn,
param: {
no: 0,
time: 100
}
}, {
fn: asyncFn,
param: {
no: 1,
time: 40
}
}, {
fn: asyncFn,
param: {
no: 2,
time: 1000
}
}, {
fn: asyncFn,
param: {
no: 3,
time: 10
}
}];
function stepAsyncFn(steps, cb) {
let errs = [],
results = [];
let iter = function*() {
let fn, param;
for (let len = steps.length, i = 0; i < len; i++) {
fn = steps[i]["fn"];
param = steps[i]["param"];
yield fn(iter, param, function(err, result) {
// console.log("fn callback err:", err, "result:", result);
errs.push(err);
results.push(result);
});
// console.log("OK, sleeping now...");
// yield sleep(iter, 2000);
}
return cb && cb(errs, results);
}();
iter.next(); // Fire!
}
// Execute!
stepAsyncFn(steps, function(errs, results) {
console.log("all fn complete errs:", errs, "results:", results);
});
/* Console log:
I am no.0
I am no.1
I am no.2
I am no.3
all fn complete
errs: [null, null, null, null]
results: ["I am no.0", "I am no.1", "I am no.2", "I am no.3"]
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment