Created
March 15, 2018 14:04
-
-
Save coffee-mug/84fbef02e16379d002a768746d27045f to your computer and use it in GitHub Desktop.
Chain promises in 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
// Promises, the big deal | |
// Here's a, a small function that returns a promise, | |
// which resolves itself at a random time between 0 and 1/2s, returning "My question num" | |
var a = (num) => { | |
return new Promise( (res, rej) => { | |
// return "My question num" between immediately and 1/2 s. | |
return setTimeout( () => res(`My question ${num}`), 500 * Math.random()) | |
}) | |
} | |
// Now imagine that we want to log a list of questions, that are all being received at a random | |
// time between 0 and 1/2s (our function a actually) in order (like question 1 then 2 then 3 then 4) | |
// The first naive way of doing it could be to do: | |
[1,2,3,4].map(a).forEach(promise => promise.then(question => console.log(`%c ${question}`, 'color: red') )) | |
// We create a list of promises through passing each number to the a function above (map(a)) | |
// and then, we execute each promise with then, get the question that has been resolved and log it. | |
// Unfortunately, it won't display them in order (printed in red in the console if you open it) | |
// To keep the order (chaining) we have to : | |
// 1 set a promise | |
// 2 execute it with .then(result => result) | |
// 3 inside the then, create the next promise to call | |
// (to force it to be executed after the first promise) | |
// chain function does exactly that, using recursion. | |
// Good free book to understand recursion in JS: https://leanpub.com/javascriptallongesix/read | |
// ITS FREE, ONLINE, IN JAVASCRIPT | |
var chain = ([f, ...rest]) => { | |
// [f, ...rest] is called destructuring assignment: it expects a list as an argument | |
// and will automatically bind f to the first element of the list and rest to the | |
// remaining elements of the list. Useful for recursion. | |
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment | |
if (rest.length == 0) { | |
// Stop recursion condition: if there is no more arguments than one to which we can apply the function | |
// Then, we simply execute it one more time on this element and return to stop the recursion. | |
return a(f).then(q => console.log(q)); | |
} | |
// we apply the function a, which returns a promise, log the resolved result to the console | |
// and recurse on remaining elements. | |
return a(f).then(q => { console.log(q); return chain([...rest]) }); | |
} | |
/* Should output in the console | |
* My question 1 | |
* My question 2 | |
* My question 3 | |
* My question 4 | |
* My question 5 | |
**/ | |
chain([1,2,3,4,5,6]); | |
/** Good references to master all of this | |
* Javascript allongé, le meilleur livre sur le JS et la programmation fonctionnelle, version ES5 ou ES6. | |
https://leanpub.com/javascriptallongesix/read | |
* Chaining promises with reduce - MDN | |
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce#Running_Promises_in_Sequence | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment