Наконец, вызывается сразу перед выполнением обещаний

Я пытаюсь выполнить проверку, как только обещание будет выполнено в 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.