Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing another promise to a promise handler

I expected the promise handler to log the promise p1 (not the value "A") since console.log is called with p1 directly. However, it somehow logs "A". How is the promise p1 automatically resolved to "A" without then being called on it ? For example, console.log(p1) does not output "A" directly as is expected. Is something going on behind the scenes ?

var p1 = new Promise(function(resolve, reject) {
  resolve("A");
});

var p2 = new Promise(function(resolve, reject) {
  resolve(p1);
});

p2.then(function(v) {
  console.log(v)
});

EDIT: I understand that calling

p1.then((v) => return v))

returns a new promise that is fulfilled with the value v. Unless Im seriously missing something here, the "p1" reference in the second promise constructor should have been passed directly to console.log, resulting in the block

var p2 = new Promise(function(resolve, reject) {
  resolve(p1);
});

p2.then(function(v) {
 console.log(v)
});

becoming

console.log(p1).

Since console.log is called directly with p1, NOT the result of p1.then(...), p1 should not be resolved into the value "A" in the same way that printing that a another program

var promise = new Promise(function(resolve, reject) {
  resolve("B")
})

console.log(promise)

does not result in the string "B".

EDIT2: I had a misconception that the resolve parameter passed to the executor is a wrapper for unfulfilled function, which caused me tons of confusion. Check out Why does the Promise constructor require a function that calls 'resolve' when complete, but 'then' does not - it returns a value instead? for more details.

like image 243
kuan Avatar asked Sep 29 '17 14:09

kuan


People also ask

How do you call a promise inside another promise?

Here we need to first declare a Promise by using the Promise syntax, and we will be using the then() method for its execution and then inside that then() method we will create another promise by using the same Promise syntax as illustrated above, and then we will call our result of first inside that new Promise.

Can a promise return another promise?

We can apply not only normal functions to a Promise but also functions that itself return a Promise . In fact this is the domain of functional programming. A Promise is a specific implementation of a monad, then is bind / chain and a function that returns a Promise is a monadic function.

What happens if reject () method is called twice inside the promise executor function?

No. It is not safe to resolve/reject promise multiple times.

How do you handle nested promises?

In a promise nesting when you return a promise inside a then method, and if the returned promise is already resolved/rejected, it will immediately call the subsequent then/catch method, if not it will wait. If promised is not return, it will execute parallelly.


2 Answers

From the MDN documentation:

Promise.resolve(value)

Returns a Promise object that is resolved with the given value. If the value is a thenable (i.e. has a then method), the returned promise will "follow" that thenable, adopting its eventual state; otherwise the returned promise will be fulfilled with the value. Generally, if you don't know if a value is a promise or not, Promise.resolve(value) it instead and work with the return value as a promise.

p1 is thenable, so the return promise follows it.

like image 109
Quentin Avatar answered Oct 14 '22 00:10

Quentin


Resolving a promise to another promise will automatically make it wait for the other promise's result.

This is what makes promises chainable (returning further promises in then() callbacks).

like image 25
SLaks Avatar answered Oct 14 '22 00:10

SLaks