Promise执行顺序(上)

275 阅读2分钟

代码执行顺序

const first = () =>
    new Promise((resolve, reject) => {
        resolve(2);
        console.log(3);
        let p = new Promise((resolve, reject) => {
            console.log(7);
            resolve(1);
        })
        p.then(arg => {
            console.log(arg);
        })
    })
first().then(arg => {
    console.log(arg);
})
console.log(4);

Promise构造函数

function Promise(resolver) {
  if (typeof resolver !== 'function') {
    throw new TypeError('resolver must be a function');
  }
  this.state = PENDING;
  this.queue = [];
  this.outcome = void 0;
  if (resolver !== INTERNAL) {
    safelyResolveThenable(this, resolver);
  }
}
  1. 执行first()
  2. new Promise进入构造函数
  3. 执行safelyResolveThenable
function safelyResolveThenable(self, thenable) {
  // Either fulfill, reject or reject with error
  var called = false;
  function onError(value) {
    if (called) {
      return;
    }
    called = true;
    handlers.reject(self, value);
  }

  function onSuccess(value) {
    if (called) {
      return;
    }
    called = true;
    handlers.resolve(self, value);
  }

  function tryToUnwrap() {
    thenable(onSuccess, onError);
  }

  var result = tryCatch(tryToUnwrap);
  if (result.status === 'error') {
    onError(result.value);
  }
}
  1. 实际执行tryToUnwrapthenable(onSuccess, onError);
  2. thenable = 当初Promise传入的以下代码
(resolve, reject) => {
    resolve(2);
    console.log(3);
    let p = new Promise((resolve, reject) => {
        console.log(7);
        resolve(1);
    })
    p.then(arg => {
        console.log(arg);
    })
}
  1. 执行resolve(2)
  2. 即执行
function onSuccess(value) {
    if (called) {
      return;
    }
    called = true;
    // value = 2
    handlers.resolve(self, value);
}
  1. handlers.resolve
handlers.resolve = function (self, value) {
  // 每次执行都过tryCatch,这也是为什么能最后Catch到的原因
  var result = tryCatch(getThen, value);
  if (result.status === 'error') {
    return handlers.reject(self, result.value);
  }
  var thenable = result.value;
  // thenable = undefined
  if (thenable) {
    safelyResolveThenable(self, thenable);
  } else {
    // 进入这里
    self.state = FULFILLED;
    // outcome记录2
    self.outcome = value;
    var i = -1;
    // self.queue = []
    var len = self.queue.length;
    // 没有执行的
    while (++i < len) {
      self.queue[i].callFulfilled(value);
    }
  }
  return self;
};
  1. 一样的执行顺序
  2. 打印7,执行resolve(1);
  3. getThen(这步返回undefined),与本题无关
function getThen(obj) {
  // Make sure we only access the accessor once as required by the spec
  var then = obj && obj.then;
  // 判断传入参数是不是Promise
  if (obj && (typeof obj === 'object' || typeof obj === 'function') && typeof then === 'function') {
    return function appyThen() {
      then.apply(obj, arguments);
    };
  }
}
  1. then
Promise.prototype.then = function (onFulfilled, onRejected) {
  if (typeof onFulfilled !== 'function' && this.state === FULFILLED ||
    typeof onRejected !== 'function' && this.state === REJECTED) {
    return this;
  }
  // 新生成Promise
  var promise = new this.constructor(INTERNAL);
  // this.state = "FULFILLED"
  if (this.state !== PENDING) {
    // 进入这里resolver = onFulfilled
    var resolver = this.state === FULFILLED ? onFulfilled : onRejected;
    // this.outcome = 1, promise = 新构造的
    unwrap(promise, resolver, this.outcome);
  } else {
    this.queue.push(new QueueItem(promise, onFulfilled, onRejected));
  }

  return promise;
};
  1. unwrap
function unwrap(promise, func, value) {
  // task = immediate里面的funciton
  immediate(function () {
    var returnValue;
    try {
      returnValue = func(value);
    } catch (e) {
      return handlers.reject(promise, e);
    }
    if (returnValue === promise) {
      handlers.reject(promise, new TypeError('Cannot resolve promise with itself'));
    } else {
      handlers.resolve(promise, returnValue);
    }
  });
}

immediate.js

var Mutation = global.MutationObserver || global.WebKitMutationObserver;
var called = 0;
var observer = new Mutation(nextTick);
var element = global.document.createTextNode('');
observer.observe(element, {
    characterData: true  // 设置true,表示观察目标数据的改变
});
// 改变element.data数据变化
scheduleDrain = function () {
    // (called = ++called % 2) 对一个整数called对2取模,得到0或者1
    // element.data数据变化一次,执行一次nextTick回调
    element.data = (called = ++called % 2);
};
// 当queue = [], draining = undefined
function immediate(task) {
    if (queue.push(task) === 1 && !draining) {
        scheduleDrain(); // 执行scheduleDrain
    }
}
var draining;
var queue = [];

function nextTick() {
    draining = true;
    var i, oldQueue;
    // 这段代码的意思
    // 在nextTick执行过程中,queue队列里面添加进来的任务
    // 全部执行完毕
    var len = queue.length;
    while (len) {
        oldQueue = queue;
        queue = [];
        i = -1;
        while (++i < len) {
            // i 从0开始执行,先进先执行,满足队列的执行机制,执行完成后
            oldQueue[i]();
        }
        // 判断queue是否有新任务加入。改变了len
        // 如果len改变,继续上面的while不退出
        len = queue.length;
    }
    draining = false;
}
  1. immediate
// 当queue = [], draining = undefined
function immediate(task) {
    if (queue.push(task) === 1 && !draining) {
        scheduleDrain(); // 执行scheduleDrain
    }
}
  1. scheduleDrain执行
  2. 执行first().then
  3. 再次执行14步骤,但是只push,不执行里面的scheduleDrain
  4. 然后打印console.log(4);
  5. 现在执行nextTick回调
  6. 按照先进先出,打印1,2