2015-07-31 6 views
1

Я пытаюсь сравнить два подхода к использованию обещаний в угловом после чтения this article.Поведение обещания с угловым

Поэтому я использую этот код для сравнения с/без использования отложенных. Примечание: адрес http://localhost:1337/error возвращает ответ с состоянием http 500 и сообщение «ошибка» в качестве данных об ошибках (это предполагаемое поведение).

.controller("HomeCtrl", function($q, $http) { 
    function doAsyncCallDeferred() { 
     var deferred = $q.defer(); 
     $http.get("http://localhost:1337/error") 
      .catch(function(errorData) { 
       // error 
       deferred.reject(errorData.data); 
      }); 
     return deferred.promise; 
    } 

    function doAsyncCall() { 
     return $http.get("http://localhost:1337/error") 
      .catch(function(errorData) { 
       // error 
       return errorData.data; 
      }); 
    } 

    doAsyncCallDeferred() 
     .then(function (data) { 
      console.log("with deferred success"); 
      console.log(data); 
     }) 
     .catch(function(errorData) { 
      // data should be "error" 
      console.log("with deferred error"); 
      console.log(errorData); 
     }); 

    doAsyncCall() 
     .then(function (data) { 
      console.log("without deferred success"); 
      console.log(data); 
     }) 
     .catch(function(errorData) { 
      // data should be "error" 
      console.log("without deferred error"); 
      console.log(errorData); 
     }); 
}) 

Но я смущен результат:

with deferred error 
error 
without deferred success 
error 

Я предполагал, что с обоих подходов, подвох обратного вызова будет выполняться, но это, кажется, что это не так. Кто-нибудь может объяснить это поведение, пожалуйста?

+0

Я думаю, это потому, что строки: 'deferred.reject (errorData.data);'. Он отвергает отложенные, поэтому вне функции все еще захватывает. Не могли бы вы проверить? – Joy

+0

Избегайте [отложенного антипаттера] (http://stackoverflow.com/q/23803743/1048572) (в 'doAsyncCallDeferred')! Обратите внимание, что вы никогда не выполняете отложенное, когда вызов ajax преуспевает. – Bergi

+1

@ Bergi, он * это * пытается избежать этого - первая ссылка на статью об отложенном антипаттере –

ответ

2

.then и .catch являются асинхронными «эквивалентами» от try/catch. Когда вы .catch что-то, это означает, что вы «обработали» его.

В doAsyncCall вы обработка «исключение» (который является отказом обещания) и возвращение errorData.data как data к следующим .then. Если вы хотите «повторно бросить», то return $q.reject(errorData.data).

В doAsyncCallDeferred вы явно отвергаете обещание.

В качестве примера эквивалентны следующие своим пользователям:

function doAsyncCallDeferred() { 
    var deferred = $q.defer(); 
    $http.get("http://httpstat.us/500") 
     .then(function(response){ 
      deferred.resolve(response.data); 
     }) 
     .catch(function(errorData) { 
      deferred.reject(errorData.data); 
     }); 
    return deferred.promise; 
} 

function doAsyncCall() { 
    return $http 
      .get("http://httpstat.us/500") 
      .then(function(response){ 
       return response.data; 
      }) 
      .catch(function(errorData){ 
       return $q.reject(errorData.data); 
      }); 

} 
+0

Рабочая демонстрация: http://jsfiddle.net/39heccq1/ – Joy

+0

@ Джой, я бы на самом деле продемонстрировал ее так: http://jsfiddle.net/ mvrm0b1w/1 /, так как часто желательно «обрабатывать» ошибку для генерации нового сообщения об ошибке для конкретной службы. (и, фактически, сделать его эквивалентным результату 'doAsyncCallDeferred') –

+0

Вы сделали это неправильно? Кажется точно так же, как и моя демонстрация. – Joy

Смежные вопросы