0

I am working with promises and here is my code:

function call1() {
   return new Promise(function(resolve, reject) {
     resolve('resolved from call 1');
   });
}

function call2(result) {
    return new Promise(function(resolve, reject) {
    resolve(result + ' - resolved from call 2');
  });
}

function callP() {
  call1()
    .then(result => call2(result))
    .then(function(result) {
      console.log(result);
    });
}
callP();

This gives me the output:

resolved from call 1 - resolved from call 2

But when I change:

.then(result => call2(result)) 

to:

.then(function(result) {
  call2(result);
})

The result is undefined.

As per my understanding:

function(result) {
    call2(result);
} 

and:

result => call2(result)

Mean the same thing. Am I doing anything wrong here?

Andrew Li
  • 55,805
  • 14
  • 125
  • 143
Kanishka Panamaldeniya
  • 17,302
  • 31
  • 123
  • 193
  • `result => call2(result)` is an implicit return whereas `function` syntax requires an explicit return to do the same thing – Damon Jul 11 '17 at 04:28
  • @GerardoFurtado Interestingly enough, the canonical doesn't go over implicit returns. I guess it's more semantic and side-effect difference than syntactic difference. – Andrew Li Jul 11 '17 at 04:33
  • @AndrewLi You are right, it doesn't mention the `return`. I'll reopen this question. – Gerardo Furtado Jul 11 '17 at 04:35

3 Answers3

4
.then(result => call2(result)) 

Implicitly returns the result of call2 and is equivalent to this:

.then(result => { return call2(result); })

What you're looking for is this:

.then(function(result) {
    return call2(result);
})
Andy Gaskell
  • 31,495
  • 6
  • 74
  • 83
3

They are not the same. This arrow function:

result => call2(result)

Implicitly returns the return value of call2(result) because arrow functions allow for the following syntax:

( … ) => expression

Where expression is the return value of the arrow function. For example:

() => 1 + 1

Is the same as:

() => { return 1 + 1 }

And:

function() {
  return 1 + 1;
}

The regular function does not return anything:

function(result) {
  call2(result);
}

That callback doesn't return anything explicitly (it defaults to undefined). Because you do not return anything, the second chained then receives undefined as the value of the result argument and thus logs undefined. To achieve the same effect, return the value explicitly:

return call2(result);

This will pass the result of the first then to the second then and log correctly. Also note, arrow functions and regular functions bind this differently. this in arrow functions is the this of the enclosing scope -- they don't bind it themselves while regular function expressions depend on how they're called -- usually being window or undefined in strict mode. Besides the syntactical differences, I recommend reading Felix Kling's phenomenal answer on the topic.

Andrew Li
  • 55,805
  • 14
  • 125
  • 143
2

The main issue here is that you forgot to return a value in your first function. So if return call2(result) in the first function, like what i've done below:

function(result) {
    return call2(result);
} 

You will get the same result as using the arrow function you mentioned in your second code:

result => call2(result)

With regards to if the first function is the same as the second one ( assuming you've added the return in the first function), while they may achieve the same thing, they are not quite the same. The main difference is with the context of this. I quite like the explanation of arrow function and how it affects the value of this by MDN which you can view here.

Mμ.
  • 8,382
  • 3
  • 26
  • 36
  • Well, they technically aren't equal because of the different for the value of `this`, but in this case `this` isn't being used so they would perform the same if the `return` was added. I think it's important to not let anyone forget that different with arrow functions. – jfriend00 Jul 11 '17 at 04:39