реализация функции минимального обещания для понимания других структур обещаний - PullRequest
0 голосов
/ 17 ноября 2018

Я пытался понять архитектуру вызова обещания в javscript, и вот что я предположил, что происходит за кулисами

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);
  }
}

крошечный 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;
}

крошечное закрытие 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;
}

Я хочу понять,почему через массив выполняется цикл для обработки следующей функции, связанной с разрешением!что мне не хватает в моей архитектуре?

1 Ответ

0 голосов
/ 18 ноября 2018

в моей библиотеке после каждого resolve вызова я вызываю следующий обратный вызов в стеке и сдвигаю массив на один

Это очередь обратного вызова, а не обещание. Обещание может быть выполнено только один раз. При создании цепочки обещаний .then() он просто создает несколько объектов обещаний, каждый из которых представляет асинхронный результат после шага.

Возможно, вы захотите взглянуть на основные функции обещаний .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...