Подтвердить что ты не робот

Немедленно верните разрешенное обещание, используя 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?

4b9b3361

Ответ 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;
};

Надеюсь, что это поможет.