Group to see, do not understand the check, check do not understand the line source.
The title
Promise.resolve().then(() = > {
console.log(0)
return Promise.resolve(4)
}).then(res= > {
console.log('res: ', res)
})
Promise.resolve().then(() = > {
console.log(1);
}).then(() = > {
console.log(2);
}).then(() = > {
console.log(3);
}).then(() = > {
console.log(5);
}).then(() = >{
console.log(6);
})
Copy the code
The output
One, two, three, four, five, six
logic
Then (() => {console.log(1)})
And the same goes for everything else.
After initially executing both promises.resolve () :
microTask: `0 1`
Copy the code
This is a big pity. Logically, 4 should be added to the micro-task.
But return the fulfilled Promise in then,
The then method execution of the returned Promise is placed internally into the microtask queue for execution.
microTask: 1 Promise.resolve(4).then
microTask: Promise.resolve(4).then 2
Copy the code
This will be a pity because the Promise. Resolve (4) state is very depressing.
Then APPLY for a micro-task in order to synchronize 0 Promise. Resolve (4). Then the state of pity.
Resolve (4). Then after the Promise is initialized,
So a microtask wait is required.
Resolve (4) will be the big pity state of resolve(4), which incidentally synchronizes the Promise returned by external 0.
Note: the Promise returned by 0 is the state of sync promise.resolve (4).then
MicroTask: 2 Synchronization status microTask: synchronization status 3 microTask: 3 4 Final output: 1 2 3 4 5 6Copy the code
Prove that the Then method is put into the microqueue
0 is modified to
.then(() => { console.log(0) // return Promise.resolve(4) return { then(resolve) { console.log('then') resolve(4) }, }})Copy the code
Output: 0, 1 then 2 res: 4, 3, 5, 6Copy the code
You can see that the THEN method is put into the microtask queue.
This then method synchronizes the fulfilled state directly to the Promise state returned by 0, so the next micro task will output the RES.
The source code
I dug through the source code of promise. Js of V8 that was not implemented in V8 Torque(TQ V8 internal language) or C in version 4.3.65. It was implemented in C after version 5 and tQ in the latest version.
Resovle (x) is equivalent to new Promise(rs => RS (x)), both behavior is consistent, interested can try.
The source address
deferred
Deferred is an object created internally for chained calls. The then method returns a Deferred, and the Promise object is also a Promise
Promise.then/ returns Thenable to create this object. It seems to me that the latest return to Thenable does not create this object, instead using an external Deferred object
function PromiseDeferred() { if (this === $Promise) { // Optimized case, avoid extra closure. var promise = PromiseInit(new $Promise(promiseRaw)); return { promise: promise, resolve: function(x) { PromiseResolve(promise, x) }, reject: function(r) { PromiseReject(promise, r) } }; } else { var result = {}; result.promise = new this(function(resolve, reject) { result.resolve = resolve; result.reject = reject; }) return result; }}Copy the code
understand
=> indicates the return, -> indicates the step, and Deferred Object is deferred for short
Note: Subsequent “synchronous state” microtasks are only for non-pending states
then(onResolve) => deferred -> onResolve => Promise(fulfilled) -> Promise(fulfilled).then(deferred.resolve, Deferred. Reject) -> Put a microtask "sync state" to the external deferred -> so that the chain call then(onResolve) => Deferred -> onResolve => Thenable -> deferred.resolve(Thenable) -> then(onResolve).then(onResolve2, onReject2) -> deferred.promise.then(onResolve2, OnReject2) -> defeerred -> defeerred -> defeerRed -> defeerred -> defeerred -> defeerred -> defeerred -> defeerred Method, OnResolve2 will be wrapped internally so -> execute the then method simultaneously when Thenable is converted to thenDeferred -> Determine thenDeferred. Promise status after executing the then method -> ThenDeferred. Promise. Then (onResolve onReject) - > mount deferred. Promise. Then parameters to thenDeferr. Promise. ThenCopy the code
Return the Thenable object:
Promise.resolve().then(() => {console.log(0) return {console.log('then') {console.log('then') resolve(4) }, } }) .then(res => { console.log('res: ', Res)}) equals promise.resolve ().then(() => {console.log(0)}).then(() => {console.log('then') return 4 }) .then(res => { console.log('res: ', res) })Copy the code
This is the implementation logic in version 4.3.65 (my understanding, wrong for you
Conclusion source
The return Promise always requires a microtask, but Thenable does not, but this is 4. Many code implementation, after the code changes a lot, but the idea is generally the same. B: I think so. I can’t read the rest of it
speculation
Because this is the code of 4.3.65, the logic that does not conform to the previous reasoning is normal. Although the code of this version is quite elegant, it may be that in order to achieve a more elegant implementation, the THEN of Thenable/Promise should be treated equally and implemented in the micro-task. There is no need to do special processing. So both then methods are processed in the microtask queue. B: Reasonable, I thought
Second, my source code understands that a promise that returns a Thenable object must be followed by a then method to implement Thenable. Then, so you need to change and unify the behavior. (Maybe I misunderstood?
So why does the current version return Promise with two microtasks and Thenable with one
reasonable
I assume that in later versions, any “Then” will be put into the microtask queue, if it’s a Promise:
The synchronization state is essentially passed to a Promise’s then method (deferred.resolve, deferred.Reject).
Don’t discuss the Rejected state (or rather, this is similar to the fulfilled state)
PromiseState is fulfilled/Thenable Object: Then (() => promise.resolve (4)) -> promise.resolve (4) => This is a big pity and non-deferred -- > internal processing -- > There is a THEN method to hijack and put it into the microtask queue for execution -- > Because the THEN method does not pass in parameters, This will be a big pity. OnResolve = => x -> onResolve => x -> onResolve => X -> onResolve => X -> onResolve => X -> onResolve => X -> onResolve => X -> onResolve => X -> onResolve => X -> onResolve => X -> onResolve => X). Then (d) -> Promise.resolve(). Then (() => ({then(rs) {rs(4)}}) -> Thenable D. object to synchronize directly with the outside, -> so only one microtask is needed to execute the then method. The new internal implementation should be more elegant than this, Promise.resolve(4). Then (res => res) -> promise.resolve (4) -> promise.resolve Put the current promise.then into the sync state microtask so that you can sync the state to the Deferred object for example: Promise.resolve().then(() => promise.resolve (4).then(res => res)) Promise.resolve().then() Promise.resolve(4).then(res => res) returns deferred(thenD) Resolve (4).then(res => res).then(synchronize d) so that D can update the status in timeCopy the code
According to the
The previous code was changed to
Promise.resolve().then(() => {console.log(0) return promise.resolve (4).then(res => res) // Pending status Mount synchronization status microtasks }).then(res => { console.log('res: ', res) })Copy the code
Output: 0 1 2 3 4 5 6
conclusion
On a whim, bold guess, people want to write, such as mistakes, scold.
Internal implementation is well written results, I believe anyway. (doge