The short question is: is a promise just a way to separate the code into different sections, so that when task 1 is done, do this task 2, 3, and 4. And when task 2 is done, do task 5, and so on? These tasks typically can take a long time, such as a fraction to a second to a few seconds, to even minutes or it may even fail. In other words, when something is done or has failed, how to continue?
The longer details are:
There seems to be an increasing use of promises. Is the main idea of promises about "being able to continue"? Or "continuable"?
It seems that in ES6 JavaScript, the promise is just a value, or a promised value (or a promised task), with a state. And then, a promise is "thenable", meaning that the programmer can specify, "what if the promise succeeded, then do __" or "what if the promise failed, then do __". It is mainly about being able to control the continuity of code.
(the state
of a promise above can be pending
, fulfilled
, or rejected
, but it is somewhat implementation level details that we don't have to be concerned about.)
This seems especially important in a single threaded, single process environment, such as in JavaScript, when we fetch some network resource, and then when it is done, do something else. Since we don't have the ability to start a new thread to do that, and have the luxury to have the network data fetching "block" us (wait and wait until the complete data returns), so we need to say, "fetch data", and let me go on, and wake me up, and now, when waking me up, do this action action1
, and this is exactly what promise.then(action1)
does. (there really is no "wake me up", but just "do what I told you" but call me as a way to wake me up).
If we can have a thread, then we can do "fetch this data and then fill in table and graph" in a new thread. This thread can be "blocked" when fetching data from the network. And we don't have to worry about the main program being blocked.
Using a promise is almost like some lines of code:
if (doTask1() === statusSuccess)
then
...
else
...
except now, with promises, the "then" part and "else" part is like being chopped up into pieces, and they don't continue to run in one shot. They run only when ready.
And the code becomes:
new Promise(function(...) {
// do something
})
.then(function() { ... })
.catch(function() { ... })
.finally(function() { ... });
But it also seems it is not strictly "single threaded", because if the network call cannot continue to fetch data, then what good is a promise? There are still extra processes or threads, but it is just system operations. (or perhaps user operations, if it is some kind of workers like Web Worker or Worker thread).
The above is with "chained promises", about do this, let me go on, and when done, let me know and continue with ___. And a series of these. There can also be this: do a few things in parallel, and let me go on, and let me know (1) when everything is done, or (2) when one of them is done.
The (1) above can be to get data from 3 computer servers to get something all needed, and don't wake me up until all tasks are done. The (2) above can be, if 3 computer servers do the same complicated computation, and sometimes server 2 is faster, sometimes server 1 or 3, and they come back with the exact same answer. So if any of them come back, wake me up and continue with what I told you to do.
The (1) above is done by ES6 JS .all()
:
Promise.all([promise1, promise2, promise3]).then(function(values) {
console.log(values);
// the values of all promises given as an array of items
});
The (2) above is done by .race()
:
Promise.race([promise1, promise2, promise3]).then(function(value) {
console.log(value);
// whatever is faster
});
And there really is no "wake me up". It merely is "continue with what I told you." (because we merely say: myPromise.then(task1, task2)
).
There also is a subtle difference between an observable and a promise (or thenable). If we register an observer to watch on something after it has already succeeded, the observer is not notified. However, with a promise, since it is about controlling what to do next, so if we say myPromise.then(task1)
after myPromise
has succeeded, the task1
will still run. It is like, when the original task (the promise) is done, do this task1
, and it doesn't matter if the original promise took 1 ns or 10 minutes or that it is already done. If it is done, always make sure to run task1
.
So perhaps in one line, promises is about: fragments of tasks, and the program can specify, do task 1 and do this task 2 next when task 1 is done, etc, quite similar to a master plan on a piece of paper that a boss or a planner would hand to you. (and that many of these tasks can't continue to run and let us wait indefinitely, but is when it is finally done (or fail), then do what's next).