实现最低限度的最低承诺功能以了解其他承诺框架

时间:2018-11-17 17:12:17

标签: javascript promise

我一直试图理解javscript中的promise调用背后的架构,这是我认为正在幕后发生的事情

function Promise() {

  this.stack = [];

  this.then = function(fn) {
    this.stack.push(fn);
    return this;
  }

  this.resolve = function(data) {

    if (this.stack.length) {
      var cb = this.stack[0];

      this.stack.shift();
      cb.call(null, {
        resolve: this.resolve.bind(this)
      }, data);
    }

  }
}


// --- below is a working implementation --- //

var bar = function() {
  var promise = new Promise();
  setTimeout(function() {
    console.log("1");
    promise.resolve();
  }, 2000);
  return promise;
}

bar().then(function(p) {
  setTimeout(function() {
    console.log("2");
    p.resolve();
  }, 1000);
}).then(function(p) {
  setTimeout(function() {
    console.log("3");
    p.resolve();
  }, 500);
}).then(function(p) {
  setTimeout(function() {
    console.log("4");
    p.resolve();
  }, 300);
});

在我的库中,每次resolve调用之后,我正在调用堆栈中的下一个回调并将数组移位一个

但是在我链接的其他库中,每当第一个承诺被解决时,就会在遍历整个数组的同时循环运行,同时不断调用回调堆栈。

D.js

function execCallbacks() {
  /*jshint bitwise:false*/
  if (status === 0) {
    return;
  }
  var cbs = pendings,
    i = 0,
    l = cbs.length,
    cbIndex = ~status ? 0 : 1,
    cb;
  pendings = [];
  for (; i < l; i++) {
    (cb = cbs[i][cbIndex]) && cb(value);
  }
}

tiny Promise.js

_complete: function(which, arg) {
  // switch over to sync then()
  this.then = which === 'resolve' ?
    function(resolve, reject) {
      resolve && resolve(arg);
    } :
    function(resolve, reject) {
      reject && reject(arg);
    };
  // disallow multiple calls to resolve or reject
  this.resolve = this.reject =
    function() {
      throw new Error('Promise already completed.');
    };
  // complete all waiting (async) then()s
  var aThen, i = 0;
  while (aThen = this._thens[i++]) {
    aThen[which] && aThen[which](arg);
  }
  delete this._thens;
}

tiny closure Promise.js

function complete(type, result) {
  promise.then = type === 'reject' ?
    function(resolve, reject) {
      reject(result);
    } :
    function(resolve) {
      resolve(result);
    };

  promise.resolve = promise.reject = function() {
    throw new Error("Promise already completed");
  };

  var i = 0,
    cb;
  while (cb = callbacks[i++]) {
    cb[type] && cb[type](result);
  }

  callbacks = null;
}

我想理解,为什么在数组中循环运行以处理链接到resolve的下一个函数! 我在建筑中缺少什么?

1 个答案:

答案 0 :(得分:1)

  

在我的库中,每次resolve调用之后,我正在调用堆栈中的下一个回调并将数组移位一个

这是一个回调队列,不是承诺。一个承诺只能解决一次。制作承诺.then()链时,它只是创建多个承诺对象,每个对象代表一步之后的异步结果。

您可能想看看the core features of promises