Контроль, когда срабатывает обратный вызов `.then()`

У меня есть длинная цепочка обещаний, которые пронизывают модуль моего кода. Я не знаю заранее, сколько обещаний я выполню, и при этом у меня нет места ни от одного обещания, ни от другого обещания (то есть я не могу выполнить Promise.join()).

Моя проблема в том, что у меня есть then() обратные вызовы, прикрепленные к нескольким обещаниям в этой цепочке. Как я могу контролировать, какой из них уволен последним?

ОБНОВЛЕНИЕ: Вот упрощенный пример:

var aFn = function () {
  return bFn().then(someFn);
};

var bFn = function () {
  return new Promise(function (resolve, reject) {
    if (a) return resolve();
    else return reject();
  });
};

aFn().then(anotherFn);

Моя проблема в том, что .then() в aFn().then(anotherFn) вызывается раньше bFn().then(someFn),

Вот несколько фрагментов кода, которые помогут проиллюстрировать мою проблему:

strategy.js

execute: function (model, options) {
  options.url = this.policy.getUrl(model, this.method, options);
  options.collection = this.policy.getCollection(model, options);
  options.model = model;
  // This is a Promise that eventually calls get()
  return this.sync(model, options);
},

get: function (key, options) {
  var updateCollection = this._getUpdateCollection(options);
  var getFromCache = _.bind(this.store.get, this.store, key, options);
  if (updateCollection) {
    // updateCollection received a promise from store-helpers.js:proxyGetItem()
    return updateCollection().then(
      function (collection) {
        var modelResponse = collection.policy.findSameModel(collection.raw, options.model);
        return modelResponse ? modelResponse : getFromCache();
      },
      getFromCache
    );
  } else {
    return getFromCache();
  }
},

_getUpdateCollection: function (options) {
  var collection = options && options.collection;
  var collectionControl = collection && collection.sync && collection.sync.hoardControl;
  if (collection && collectionControl) {
  var collectionKey = collectionControl.policy.getKey(collection, options);
  return _.bind(function () {
    // store.get() passes the returned promise of store-helpers.js:proxyGetItem()
    return this.store.get(collectionKey, options).then(function (rawCollection) {
      return {
        control: collectionControl,
        policy: collectionControl.policy,
        key: collectionKey,
        raw: rawCollection
      };
    });
  }, this);
}

},

store.js

// Просто прокси-функция, которая переносит синхронный get get: function (key, options) { return this.getItem.apply(this, arguments); },

getItem: StoreHelpers.proxyGetItem

магазин-helpers.js

proxyGetItem: function (key, options) {
  return Hoard.Promise.resolve()
    .then(_.bind(function () {
      return this.backend.getItem(key);
    }, this))
    .then(function (raw) {
      var storedValue = JSON.parse(raw);
      if (storedValue !== null) {
        return storedValue;
      } else {
        return Hoard.Promise.reject();
      }
   });
},

В совершенно другой части приложения у меня также есть:

var originalExecute = Hoard.Strategy.prototype.execute;
Hoard.Strategy.prototype.execute = function (model, options) {
    options.originalOptions = _.clone(options);
    if (options.saveToCacheFirst) 
        return originalExecute.call(this, model, options)
            .then(_.result(options.originalOptions, 'success'), _.result(options.originalOptions, 'error'));

    return originalExecute.call(this, model, options);
}

Я хотел бы для .then() выше стрелять последним, однако когда .resolve в store-helpers.js срабатывает, это последнее .then() обратный вызов вызывается.

1 ответ

Моя проблема в том, что .then() в aFn().then(anotherFn) вызывается раньше bFn().then(someFn)

Нет, это не так. Как вы написали в примере, это выражение эквивалентно

bFn().then(someFn).then(anotherFn)

- а пока .then() метод вызывается раньше someFn, anotherFn обратного вызова нет.

Другие вопросы по тегам