Jigsaw Puzzle Nolan Promises / A + JavaScript

I read. Several times we had a problem with promises from Nolan Lawson, but you still have questions about promises in JavaScript. At the end of the Nolan post, you can find answers to four puzzles (here I attached screenshots).

So, I have a few questions:

  • Why is doSomethingElse() in puzzle 1 undefined ? In my opinion, it should have resultOfDoSomething as in the 4th puzzle.

  • What is the difference between 3rd and 4th puzzles? In the third puzzle, in the first then we write doSomethingElse() , and in the 4th puzzle we write here only the name of the function, doSomethingElse . How is this possible? What does doSomethingElse really do inside then 4th puzzle?

  • Why doSomethingElse() function run in 3rd puzzle at the same moment as doSomething ?

Puzzle 1 and 2 Puzzle 3 and 4

+8
javascript promise es6-promise
source share
6 answers
  • Why doSomethingElse() function work in the 1st puzzle [get pass] undefined ?

Let's look at a simpler example:

 foo(); // Line #1 foo(42); // Line #2 

What is the difference between the two lines? On line # 1, we call foo, but we don’t pass it the value (hence undefined ), while on line # 2 we call foo and pass it 42.

Returning to the post:

 doSomething().then(function () { return doSomethingElse( ); // ^-- we are not passing a value }).then(finalHandler); 

How is this different from the 4th puzzle? In the 4th puzzle, we pass a link to the then function. Making a promise, a function reference allows it to be called later with the result of the promise. [one]


  1. What is the difference between 3rd and 4th puzzles? In the third puzzle [...] we write doSomethingElse() , and in the 4th puzzle we write [...] doSomethingElse .

To explain the differences in the 3rd and 4th puzzles, consider simpler examples. How the two following lines differ:

 var foo = function foo() { return 42; }; var a = foo; // line #1 var b = foo(); // line #2 

In the above snippet, a will contain a reference to the function foo , while b will contain the result of calling foo (this will be 42).


  1. Why doSomethingElse() in the 3rd puzzle starts at the same moment as doSomething ?

Like the differences between the 3rd and 4th functions, pay attention to using () before calling (or calling) the function. Here we call both doSomething() and doSomethingElse() instead of waiting for the promise to "allow" (waiting for the completion of the first call). before executing:

  • Run doSomething that returns Promise
  • Attach doSomethingElse() to the promise, but wait, doSomethingElse() calls the doSomethingElse() call so that an asynchronous process will happen and we will doSomething() promise that it returns to the doSomething() promise.
  • Attach the finalHandler function to the promise
+3
source share
 doSomething().then(function () { return doSomethingElse(); }); 

Why is doSomethingElse () in puzzle 1 undefined? In my opinion, it should have resultOfDoSomething, as in the 4th puzzle.

The promised doSomething result doSomething passed to an anonymous function (which does not even take an argument). So all that is transmitted is lost. And doSomethingElse is called without any arguments, so the first argument to the function is undefined .

 doSomething().then(doSomethingElse()); doSomething().then(doSomethingElse); 

What is the difference between 3rd and 4th puzzles? In the 3rd puzzle, we first write doSomethingElse (), and in the 4th puzzle, only the function name is written here - doSomethingElse. How is this possible? What really does SomethingElse do then in the 4th puzzle?

Functions in JavaScript are objects that you can move around as you wish. Actually, how the full callback processing works: there is a function (here, its then ) that takes the function as a parameter, which is then called.

So, in the last code, the function that is passed to then is doSomethingElse , so this is the function that is later called. But in the first we call doSomethingElse directly (with parentheses () ). So, what is passed to then is the return value of this function, which is unlikely for a function that can be evaluated after the promise is completed.

Why is the doSomethingElse () function in the 3rd puzzle running at the same time as doSomething?

As I said, the function is called immediately, at the same time you are calling doSomething . Only the return value is passed to then , which is then called after the promise is resolved.

+1
source share

Note: doSomethingElse is a function reference, and doSomethingElse() means that you call this function immediately. Here you can get the result of the function, if there is ...

About promises I realized that:

A) The then method takes the result of the previous call and passes it as a parameter to its own parameter, if it is a function.

B) Execution is delayed only if the function inside the "then" method returns something.

In these situations, we have:

Puzzle 1) resultOfDoSomething is used as a parameter for an anonymous function

 function (){ return doSomethingElse ();} 

This calls doSomethingElse() with no parameters.

Puzzle 2) an anonymous function does not return data, so the next "then" is executed immediately

Puzzle 3) the expression doSomethingElse() is the result of calling doSomethingElse. This value is used as a parameter for the "then" method, and since it is not a function (in this example!), We can move on to another "then" ...

finalHandler receives the last valid results as parameters, in this case resultOfDoSomething.

Puzzle 4) each "that" method receives as a parameter a link to a function. Each of these functions will be called with previous results as parameters. Thus, each function MUST wait for the result of the previous execution ... and here you have a queue of promises ...

+1
source share

Why is doSomethingElse() in puzzle 1 undefined ? In my opinion, it should have resultOfDoSomething as in the 4th puzzle.

Nope. resultOfDoSomething is passed to the callback that then was called with, but we just ignore it in the first code:

 doSomething().then(function(resultOfDoSomething) { // it here: ^^^^^^^^^^^^^^^^^^^ return doSomethingElse( ); // but not there: ^^ - Ooops! }); 

What is the difference between 3rd and 4th puzzles? In the third puzzle, in the first we write doSomethingElse() , and in the 4th puzzle we write here only the function name, doSomethingElse . How is this possible? What does doSomethingElse really do inside the fourth puzzle?

As you probably know, this is the difference between the called function and the function itself.

In addition, we always want to - no: must - pass the callback function to then(…) . The following two equivalents:

 promise.then(function callback(res) { … }); 
 function callback(res) { … } promise.then(callback); 

Expected - you pass the function to the call, so it is tied to the promise, as usual. But callback() (with a call) is no longer a function:

Why doSomethingElse() function run in 3rd puzzle at the same moment as doSomething ?

Because it is called immediately in the then(doSomethingElse()) - it is actually called before then , to which it is an argument. Therefore, in fact, this is called the moment after doSomething() , but at the same turn of the event loop; and two asynchronous events will be executed in parallel.

In addition, then only accepts function arguments, everything else is ignored. So there’s no chain here, it's the same as doing

 var promise = doSomething(); doSomethingElse(); promise.then(finalHandler); 

Not what we want!

Btw, they are also explained as “Advanced error No. 3: promises against factory promises” and “Advanced error No. 5: promises fail”, which I will consider as a rookie error :-)

+1
source share

I think the execution order is always the first doSomethingElse, then doSomethingElse and finalHandler. This is just JavaScript syntax.

The difference is that the arguments passed to the arguments are different.

Two functions return two promises. Two promises run order are displayed in the numbers you placed. I think that the author means the order of two promises, and not the order of the function.

 /** * Created by tshungle on 17-2-24. */ 'use strict' function doSomething() { console.log("doSomething start"); sleep(1000) console.log("doSomething end"); return new Promise(function (resolve, reject) { setTimeout(function() { console.log("Promise of doSomething is about to resolve"); resolve("doSomething resolvation") }, 2500); }); } function doSomethingElse() { console.log("doSomethingElse start"); sleep(1000); console.log("doSomethingElse end"); return new Promise(function (resolve, reject) { setTimeout(function() { console.log("Promise of doSomethingElse is about to resolve"); resolve("doSomethingElse resolvation") }, 2500); }); } function finalHandler(result) { console.log("finalHandler result is:", result); } function sleep(ms) { var stop = new Date().getTime(); while(new Date().getTime() < stop + ms) { ; } } //1 doSomething().then(function () { return doSomethingElse(); }).then(finalHandler); //2 // doSomething().then(function () { // doSomethingElse(); // }).then(finalHandler); // //3 // doSomething().then(doSomethingElse()) // .then(finalHandler); //4 // doSomething().then(doSomethingElse) // .then(finalHandler); 
+1
source share

In short - 2 simple rules to make your examples understandable:

  • Returning a value from within .then same as returning a promise that resolves to that value.

  • When you return nothing, it is the same as returning undefined , which, in turn, introduces rule number 1.

If you keep these 2 in mind, your promise puzzles become clear as day.

0
source share

All Articles