Наконец, вызывается сразу перед выполнением обещаний
Я пытаюсь выполнить проверку, как только обещание будет выполнено в angularjs.
request.then(function(res){
$ionicLoading.hide();
deferred.resolve(res);
}, function(res){
$ionicLoading.hide();
deferred.reject(res);
})['finally'](function(res){
alert(res)
}
)
Но предупреждение появляется как "undefined".
- Ожидается ли это, или я делаю что-то неправильно? Я думал, что он будет вызван только тогда, когда обещание будет разрешено/отклонено.
- Каков правильный способ достичь этого?
Спасибо
Ответы
Ответ 1
Изменить/Обновить...
Это не самый удивительный способ сделать, но простой и понятный способ. Вам нужно следить за тем, что вы хотите, наконец, оповестить, когда вы идете по цепочке promises (если у вас несколько) и просто сохраните ее в переменной.
var something = null;
request.then(function(response){
$ionicLoading.hide();
something = response;
}, function(reason){
$ionicLoading.hide();
something = reason;
}).finally(function(){
alert(something);
});
Плункер, чтобы продемонстрировать:
http://plnkr.co/edit/DrqeaCAYWTQ4iWY0NPeq?p=preview
Ответ 2
Вы делаете это правильно, проблема в том, что значение, передаваемое обратному сообщению finally
, является тем же значением, возвращаемым обратными вызовами success
или error
. Поскольку вы ничего не возвращаете, значение undefined.
Если вы добавляете предложения возврата к каждому обратному вызову, он должен работать:
request.then(function(res){
$ionicLoading.hide();
deferred.resolve(res);
return res;
}, function(res){
$ionicLoading.hide();
deferred.reject(res);
return res;
})['finally'](function(res){
alert(res)
}
)
Изменить
Кажется, что реализация Angular finally
не совсем готова передать значение обратному вызову. Однако есть и другой способ создания эффекта, который вы хотите, просто замените finally
на другой then
:
request.then(function(res){
$ionicLoading.hide();
deferred.resolve(res);
return res;
}, function(res){
$ionicLoading.hide();
deferred.reject(res);
return res;
}).then(function(res){
alert(res)
}
)
Так как promises выполняются последовательно, окончательный then
будет работать последним. И поскольку вы не возвращаете никаких других promises обратных вызовов success
и error
, последнему then
потребуется только обратный вызов success
.
В конечном итоге вы также можете использовать что-то вроде этого:
...)['finally'](function(){ }).then(function(res){
alert(res)
}
)
Ответ 3
Обратный вызов finally вызывается без аргументов.
Однако он возвращает обещание, передавая результаты.
Даже исправляя это, вы ничего не возвращаете в своих обратных вызовах, поэтому ничего не передается.
Чтобы проиллюстрировать это:
angular.module('myApp', [])
.run( function ($q) {
var defer = $q.defer();
defer.promise.then(
function ( res ) { console.log('s1> '+res); },
function ( res ) { console.log('e1> '+res); }
)
.then(
function ( res ) { console.log('s2> '+res); },
function ( res ) { console.log('e2> '+res); }
)
defer.reject(1);
});
Дает следующее:
e1> 1
s2> undefined
Обратите внимание, что второй then
был "успешным", потому что отклонение не передавалось.
Убедитесь, что ваши обратные вызовы возвращают что-то. И если вы хотите упасть на ошибку в последующем then
, убедитесь, что вы возвращаете отклонение.
var defer = $q.defer();
defer.promise.then(
function ( res ) { console.log('s1> '+res); return res; },
function ( res ) { console.log('e1> '+res); return $q.reject(res); }
)
.then(
function ( res ) { console.log('s2> '+res); return res; },
function ( res ) { console.log('e2> '+res); return $q.reject(res); }
)
Вводя это вместе, вы получите что-то вроде этого:
var defer = $q.defer();
defer.promise.then(
function ( res ) { console.log('s1> '+res); return res; },
function ( res ) { console.log('e1> '+res); return $q.reject(res); }
)
.then(
function ( res ) { console.log('s2> '+res); return res; },
function ( res ) { console.log('e2> '+res); return res; }
)
.finally (
function ( res ) {
console.log('f0> '+res+','+arguments.length);
}
)
.then(
function ( res ) { console.log('s3> '+res); return res; },
function ( res ) { console.log('e3> '+res); return $q.reject(res); }
)
defer.reject('foo');
Результат:
e1> foo
e2> foo
f0> undefined,0
s3> foo
Обратите внимание, что errback во втором then
возвратил res вместо отклонения, поэтому был вызван обратный вызов finally.