I was reading on a blog about Promises and they show a problem that I don´t get at all. The blog is: https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html.
The writer presents 4 puzzles with a grafical solution:
Puzzle #1
doSomething().then(function () {
return doSomethingElse();
}).then(finalHandler);
Puzzle #2
doSomething().then(function () {
doSomethingElse();
}).then(finalHandler);
Puzzle #3
doSomething().then(doSomethingElse())
.then(finalHandler);
Puzzle #4
doSomething().then(doSomethingElse)
.then(finalHandler);
Here doSomething() and doSomethingElse are promises.
Can anyone explain everyone detailed? On the first one I get the order of execution. On the second, I dont get why doSomethingElse and finalHandler starts and finish at the same time. On the third, I dont get why doSomething and doSomethingElse starts at the same time. Shouldn´t doSomethingElse starts at the end of doSomething? On fourth, I dont get nothing...
CodePudding user response:
Puzzle 1
// doSomething() is executed and returns a promise
doSomething().then(function () {
// when doSomething() executes successfully, execute doSomethingElse() and return the Promise
return doSomethingElse();
}).then(finalHandler); // final handler will be executed once doSomethingElse has finished, since the promise was returned
Puzzle 2
// doSomething() is executed and returns a promise
doSomething().then(function () {
// when doSomething() executes successfully, execute doSomethingElse()
doSomethingElse(); // execute doSomethingElse()
// since there is nothing returned here, the the promise will resolve immediatly, without waiting for doSomethingElse() to complete
}).then(finalHandler); // final handler will be executed immediatly after doSomethingElse() has started to execute, without waiting for a result.
Puzzle 3
In this one, both functions start at the same time because .then
expects a function as its first argument. doSomethingElse
is a function, but doSomethingElse()
is a function call. Thus it is called immediately, and .then()
takes as a first argument the return value of doSomethingElse
, which is a promise.
doSomething().then(doSomethingElse())
.then(finalHandler);
Puzzle 4
Unlike puzzle 3, the function doSomethingElse
is passed to .then()
, instead of the return value of doSomethingElse
in puzzle 3.
This means that doSomethingElse
will be called once doSomething
is done.
// the code below is a shortcut for doSomething().then(() => doSomethingElse())
doSomething().then(doSomethingElse)
.then(finalHandler);
Function vs. function call
The thing you need to understand is the difference between a function (doSomething
), and a function call (doSomething()
).
function doSomething() {
return "something";
}
const func = doSomething;
const value = doSomething();
console.log(func);
console.log(value);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
Puzzle #1 and #4 as well as Puzzle #2 and #3 are the same.
In your Puzzle #2, you start another Promise and return instantly, without awaiting it. So your finalHandler will get called immediately after doSomethingElse was started, not after it is finished. If you want that, use your Puzzle #1
In your Puzzle #3, you pass the started Promise returned by doSomethingElse() directly instead of telling js to call that function if doSomething resolved. If you want do do so, write it like that - it might help to avoid confusion
doSomething()
.then(() => doSomethingElse())
.then(() => finalHandler());