Могу ли я сделать "ленивое" обещание с помощью Bluebird.js?
Мне нужно обещание, которое ждет, пока then вызывается до его запуска. То есть, если я на самом деле не назову then, обещание никогда не запустится.
Возможно ли это?
Ответ 1
Создайте функцию, которая создает и возвращает обещание при первом вызове, но возвращает одно и то же обещание при каждом последующем вызове:
function getResults() {
if (getResults.results) return getResults.results;
getResults.results = $.ajax(...); # or where ever your promise is being built
return getResults.results;
}
Promises не работают таким образом, чтобы они могли поддерживать ленивую загрузку. Promises создаются асинхронным кодом для передачи результата. До тех пор, пока не будет вызван асинхронный код, просто нет обещаний.
Конечно, вы могли бы написать объект, похожий на обещание, который делал ленивый вызов, но код, создавший эти Promises, был бы совсем другим:
// Accepts the promise-returning function as an argument
LazyPromise = function (fn) {
this.promise = null;
this.fn = fn
}
LazyPromise.prototype.then = function () {
this.promise = this.promise || fn();
this.promise.then.apply(this.promise, arguments)
}
// Instead of this...
var promise = fn();
// You'd use this:
var promise = new LazyPromise(fn);
Лучше в этом необычном использовании сделать фактическое создание обещания ленивым (как в приведенном выше примере), а не пытаться заставить Promises сами отвечать за ленивую оценку.