Немедленно верните разрешенное обещание, используя AngularJS
Я пытаюсь обойти promises в JavaScript (в частности, AngularJS).
У меня есть функция в службе, позвоните ей fooService
, которая проверяет, загружены ли мы некоторые данные. Если он есть, я просто хочу, чтобы он вернулся, а если нет, нам нужно загрузить данные и вернуть обещание:
this.update = function(data_loaded) {
if (data_loaded) return; // We've loaded the data, no need to update
var promise = Restangular.all('someBase').customGet('foo/bar').then(function(data) {
// Do something with the data here
}
return promise;
}
У меня есть другая функция, которая затем вызывает update
функцию fooService
следующим образом:
fooService.update(data_loaded).then(function() {
// Do something here when update is finished
})
Моя проблема в том, что если нам не нужно загружать данные в функцию update
, обещание не возвращается, поэтому .then()
не вызывается в моей другой функции. Каким должен быть подход? В принципе, я хочу немедленно вернуть разрешенное обещание из функции update()
, если нам не нужно получать данные из вызова Restangular?
Ответы
Ответ 1
Нынешний принятый ответ слишком сложный и злоупотребляет отложенным анти-шаблоном . Вот более простой подход:
this.update = function(data_loaded) {
if (data_loaded) return $q.when(data); // We've loaded the data, no need to update
return Restangular.all('someBase').customGet('foo/bar')
.then(function(data) {
// Do something with the data here
});
};
Или, еще больше:
this._updatep = null;
this.update = function(data_loaded) { // cached
this._updatep = this._updatep || Restangular.all('someBase') // process in
.customGet('foo/bar'); //.then(..
return this._updatep;
};
Ответ 2
Поскольку ваше обещание использует тот же синтаксис, что и родной JavaScript, вы можете использовать и возвращать уже разрешенный JavaScript-обещание: Promise.resolve()
return(Promise.resolve("MyReturnValue"));
Ответ 3
AngularJS $q сервис поможет вам здесь. Это похоже на библиотеку обещаний Kris Kowal Q.
Если у вас есть метод async, который может вернуть обещание или значение, используйте метод $q.when. Это займет то, что когда-либо передается ему, будь то обещание или ценность и создаст обещание, которое будет разрешено/отклонено на основе обещанного обещания или разрешено, если передано значение.
$q.when( fooService.update(data_loaded) ).then(function(data){
//data will either be the data returned or the data
//passed through from the promise
})
а затем в вашей функции обновления верните данные вместо того, чтобы просто возвращать
if (data_loaded) return data_loaded;
Ответ 4
Вы можете использовать $q.defer()
следующим образом:
this.update = function (data_loaded) {
var deferred = $q.defer();
if (data_loaded) {
deferred.resolve(null); // put something that your callback will know the data is loaded or just put your loaded data here.
} else {
Restangular.all('someBase').customGet('foo/bar').then(function(data) {
// Do something here when update is finished
deferred.resolve(data);
}
}
return deferred.promise;
};
Надеюсь, что это поможет.