Last active
March 8, 2017 07:35
-
-
Save akirattii/5c3136d32aafcbd678fe8b8712af5eda to your computer and use it in GitHub Desktop.
How to execute async functions in order using pure js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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"] | |
| */ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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