如下代碼執行順序
const first = () =>
new Promise((resolve, reject) => {
resolve(2);
console.log(3);
let p = new Promise((resolve, reject) => {
console.log(7);
setTimeout(() => {
console.log(5);
resolve(6);
}, 0);
})
p.then(arg => {
console.log(arg);
})
})
first()
.then(arg => {
console.log(arg);
})
console.log(4);
複製代碼
源碼分析
- Promise1
- 執行resolve(2);
Promise1 = {
this.state = 'FULFILLED';
this.queue = [];
this.outcome = 2;
}
複製代碼
- Promise2
Promise2 = {
this.state = 'PENDING';
this.queue = [];
this.outcome = void 0;
}
複製代碼
- Promise3
Promise3 = {
this.state = 'FULFILLED';
this.queue = [];
this.outcome = void 0;
}
複製代碼
- 執行then
Promise.prototype.then = function (onFulfilled, onRejected) {
if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
typeof onRejected !== 'function' && this.state === REJECTED) {
return this;
}
var promise = new this.constructor(INTERNAL);
if (this.state !== PENDING) {
var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
unwrap(promise, resolver, this.outcome);
} else {
this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
}
return promise;
};
複製代碼
- Promise3
Promise3 = {
this.state = 'FULFILLED';
// 1個QueueItem
this.queue = [{
callFulfilled: ƒ (value)
onFulfilled: arg => { console.log(arg); }
promise: Promise {
state: ["PENDING"]
queue: [],
outcome: undefined
}
}];
this.outcome = void 0;
}
複製代碼
- Promise4
Promise4 = {
this.state = 'FULFILLED';
this.queue = [];
this.outcome = void 0;
}
複製代碼
- 執行resolve(6);
function onSuccess(value) {
if (called) {
return;
}
called = true;
handlers.resolve(self, value);
}
複製代碼
- 執行handlers.resolve
handlers.resolve = function (self, value) {
var result = tryCatch(getThen, value);
if (result.status === 'error') {
return handlers.reject(self, result.value);
}
var thenable = result.value;
if (thenable) {
safelyResolveThenable(self, thenable);
} else {
self.state = FULFILLED;
self.outcome = value;
var i = -1;
var len = self.queue.length;
while (++i < len) {
self.queue[i].callFulfilled(value);
}
}
return self;
};
複製代碼
- QueueItem
function QueueItem(promise, onFulfilled, onRejected) {
this.promise = promise;
if (typeof onFulfilled === 'function') {
this.onFulfilled = onFulfilled;
this.callFulfilled = this.otherCallFulfilled;
}
if (typeof onRejected === 'function') {
this.onRejected = onRejected;
this.callRejected = this.otherCallRejected;
}
}
複製代碼
- otherCallFulfilled
QueueItem.prototype.otherCallFulfilled = function (value) {
unwrap(this.promise, this.onFulfilled, value);
};
複製代碼
- unwrap便是immediate
- 執行微任務隊列