问题
Here I have a promise that simply resolved.
let promise = new Promise((resolve,reject)=>{
resolve("resolved");
});
The confusion for me starts when I use a Promise for return value in .then
chain like this:
promise.then(resolve=>{
console.log(resolve);
return Promise.resolve(2);
}).then(resolve=>{
console.log(resolve);
});
promise.then(resolve=>{
console.log(resolve)
return 3;
}).then(resolve=>{
console.log(resolve);
});
The output of these chains is: 1 1 3 2 Which I expected to see: 1 1 2 3
But If I turn return Promise.resolve(2);
to just return 2
like here:
promise.then(resolve=>{
console.log(resolve);
return 2;
}).then(resolve=>{
console.log(resolve);
});
promise.then(resolve=>{
console.log(resolve)
return 3;
}).then(resolve=>{
console.log(resolve);
});
I'll get the output that I thought I would get in the first place (1 1 2 3).
So does anyone here can explain why the output changes based on using and not using Promise.resolve()
?
BTW I'm asking this question just for pure ACADEMIC reason!
回答1:
The then
s of Promises resolve during a microtask. Inside a .then
, if you return a plain value, like 2 or 3, the next .then
chained onto it will run the next time the call stack is clear. But if you return a Promise, it has to be unwrapped first before proceeding to the next .then
.
In your first code, once the call stack is clear, the first microtasks run. One of them "unwraps" the Promise.resolve(2)
and queues up the .then
callback in the microtask queue. In contrast, the 3
doesn't need to be unwrapped, so its .then
runs immediately at that point, without having to wait, logging 3.
The top task of the microtask queue is then the 2
's .then
, logging 2.
All this said, in real code, you shouldn't have to rely on this sort of timing, since it's a bit confusing - if it's an issue, best to re-structure the code so that it isn't something to worry about.
回答2:
Because you are returning a new Promise in case 1, it will get resolved in the next tick
.
Each time the micro task Q is searched the promises that are in the Q get resolved (not only promises, but this is relevant for this question). In case 1 you get Promise.resolve(2)
getting resolved at the same time resolve=>{
console.log(resolve)
return 3;
}
gets resolved.
Now you next micro Q has the enclosing promise of Promise.resolve(2)
on the Q. This adds a delay between the two cases.
来源:https://stackoverflow.com/questions/60912300/what-happen-when-we-return-a-value-and-when-we-return-a-promise-resolve-from-a-t