Контроль, когда срабатывает обратный вызов `.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
обратного вызова нет.