Promise执行顺序(下)

280 阅读1分钟

以下代码执行顺序

const first = () =>
    // Promise1
    new Promise((resolve, reject) => {
        resolve(2);
        console.log(3);
        // Promise2
        let p = new Promise((resolve, reject) => {
            console.log(7);
            setTimeout(() => {
                console.log(5);
                resolve(6);
            }, 0);
        })
        // Promise3
        p.then(arg => {
            console.log(arg);
        })
    })
first()
    // Promise4
    .then(arg => {
        console.log(arg);
    })
console.log(4);
  • 答案 3 7 4 2 5 6

源码分析

  1. Promise1
  2. 执行resolve(2);
Promise1 = {
    this.state = 'FULFILLED'; 
    this.queue = [];
    this.outcome = 2;
}
  1. Promise2
Promise2 = {
    this.state = 'PENDING';
    this.queue = [];
    this.outcome = void 0;
}
  1. Promise3
Promise3 = {
    this.state = 'FULFILLED'; 
    this.queue = [];
    this.outcome = void 0;
}
  1. 执行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);
  // this.state === PENDING
  // 只有当state的状态不等于PENDING,才会进入微任务队列,否则进入自己的队列
  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;
};
  1. 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;
}
  1. Promise4
Promise4 = {
    this.state = 'FULFILLED'; 
    this.queue = [];
    this.outcome = void 0;
}
  1. 执行resolve(6);
function onSuccess(value) {
    if (called) {
      return;
    }
    called = true;
    handlers.resolve(self, value);
}
  1. 执行handlers.resolve
  • self = Promise3
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;
};
  1. QueueItem
function QueueItem(promise, onFulfilled, onRejected) {
  this.promise = promise;
  if (typeof onFulfilled === 'function') {
    this.onFulfilled = onFulfilled;
    // callFulfilled = otherCallFulfilled
    this.callFulfilled = this.otherCallFulfilled;
  }
  if (typeof onRejected === 'function') {
    this.onRejected = onRejected;
    this.callRejected = this.otherCallRejected;
  }
}
  1. otherCallFulfilled
QueueItem.prototype.otherCallFulfilled = function (value) {
  // 加入微任务队列
  unwrap(this.promise, this.onFulfilled, value);
};
  1. unwrap即是immediate
  2. 执行微任务队列