2017-06-06 08:10:00 +0000
promise, tutorial
// prom1(: promise) starts to work immediately after defined
const prom1 = new Promise((resolve, reject) => {
console.log("promise 1 started to work");
const rand = Math.random();
let timeoutFunc = setTimeout(() => {
// mimicking async
rand > 0.5? resolve("promise 1 resolved"): reject("promise 1 rejected");
}, 1000);
});
prom1.then(console.log).catch(console.log);
/* same as
prom1.then(console.log, console.log); */
// func1(: function) starts to work when called
const func1 = () => {
console.log("function 1 started to work");
const rand = Math.random();
return rand > 0.5? Promise.resolve("function 1 resolved"): Promise.reject("function 1 rejected");
/* same as
return new Promise((resolve, reject) => {
rand > 0.5? resolve("function 1 resolved"): reject("function 1 rejected");
}); */
};
func1().then(console.log, console.log);
/* thenable means returning a promise
of course, a naive function is not thenable */
const func2 = () => {
console.log("function 2 started to work");
return rand = Math.random();
};
// func2().then(console.log); // TypeError: returned value of func1 is not thenable
/* revisit prom1
instance methods (then and catch) return a resolved promise in default,
therefore manual coding for returning a promise is not needed.
*/
prom1.then().then(console.log).catch(console.log)
prom1.then()/*.then(). ... .then()*/.then(console.log, console.log) // same results
// define another promise
const prom2 = new Promise((resolve, reject) => {
console.log("promise 2 started to work");
const rand = Math.random();
// doing much longer work
let timeoutFunc = setTimeout(() => {
rand > 0.5? resolve("promise 2 resolved"): reject("promise 2 rejected");
}, 10000);
});
/* Promise.all: iterable => a promise which
resolves when all promises resolve and
rejects whenever any promise rejects */
Promise.all([prom1, prom2]).then(console.log, console.log)
/* if prom1 rejects => p.all rejects in 1 second
else if prom2 rejects => p.all rejects in 10 seconds
else both resolve => p.all resolve in 10 seconds
*/
A Promise
object needs a function (resolve, reject) => {}
as an argument to deal with an async job and then deliver its returning values.
// prom1(: promise) starts to work immediately after defined
const prom1 = new Promise((resolve, reject) => {
console.log("promise 1 started to work");
const rand = Math.random();
let timeoutFunc = setTimeout(() => {
// mimicking async
rand > 0.5? resolve("promise 1 resolved"): reject("promise 1 rejected");
}, 1000);
});
const callbackLog = val => console.log(val);
prom1.then(callbackLog).catch(callbackLog);
/* same as
prom1.then(console.log).catch(console.log); // or
prom1.then(console.log, console.log); */
console.log("hello, prom1 is working ...");
Depending on the result of prom1
’s work, which takes a second, prom1
would invoke resolve
or reject
. After it is decided, resolve
or reject
, prom1
’s methods then
and catch
take a function, any function you want to work with. In my case of output, prom1
resolves the job.
promise 1 started to work
hello, prom1 is working ...
promise 1 resolved
Also note that the order of console.log
output, it is async!
“thenable” means returning a promise. Of course, a naive function is not thenable.
const func1 = () => {
console.log("function 1 started to work");
return rand = Math.random();
};
func1().then(console.log); // TypeError: there is no then method
Below is the typical example of thenable function.
// func2(: function) starts to work when called
const func2 = () => {
console.log("function 2 started to work");
const rand = Math.random();
return rand > 0.5? Promise.resolve("function 2 resolved"): Promise.reject("function 2 rejected");
/* same as
return new Promise((resolve, reject) => {
rand > 0.5? resolve("function 2 resolved"): reject("function 2 rejected");
}); */
};
func2().then(console.log, console.log);
console.log("hello, func2 is working ...");
Also after the method then
has its job done, it returns another promise resolved with its return value (provided it exists). Therefore additional chaining is available.
/* revisit prom1
instance methods (then and catch) return a resolved promise in default,
therefore manual coding for returning a promise is not needed.
*/
prom1.then().then(console.log).catch(console.log)
prom1.then()/*.then(). ... .then()*/.then(console.log, console.log) // same results
Class methods Promise.all
and Promise.race
is here for us. In this post, only Promise.all
method is explained via the following code.
// define another promise along with prom1
const prom2 = new Promise((resolve, reject) => {
console.log("promise 2 started to work");
const rand = Math.random();
// doing much longer work
let timeoutFunc = setTimeout(() => {
rand > 0.5? resolve("promise 2 resolved"): reject("promise 2 rejected");
}, 10000);
});
/* Promise.all: iterable => a promise which
resolves when all promises resolve and
rejects whenever any promise rejects */
Promise.all([prom1, prom2]).then(console.log, console.log)
Promise.all
takes many promises and invoke next step if all promises resolve, or any promise rejects. There are possible outcomes for example,
prom1
rejects => Promise.all
rejects in a second,prom2
rejects => Promise.all
rejects in 10 seconds,Promise.all
rejects in a second right after prom1
rejects,Promise.all
resolve in 10 seconds.You may check another method, namely Promise.race
. Also MDN documents with its various examples would be helpful.