2015-03-16 5 views
8

Наблюдая за множеством видеороликов Egghead.io, я заметил, что общий шаблон - это возврат пользовательского обещания и его устранение в обратных вызовах.

.factory('myFact', function($q, $http) { 
    return { 
     getData: function() { 
      var deferred = $q.defer(); 
      $http.get('/path/to/api') 
       .success(function(data) { 
        deferred.resolve(data); 
       }); 
      return deferred.promise; 
     } 
    }; 
}); 

Я обычно пишу это как:

.factory('myFact', function($http) { 
    return { 
     getData: function() { 
      return $http.get('/path/to/api') 
       .then(function(res) { 
        return res.data; 
       }); 
     } 
    }; 
}); 

Есть ли какое-либо преимущество возвращения $q.defer() обещания, а не $http обещания? Подходы похожи на меня.

+2

Я бы счел это [отсроченным антипаттером] (https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns#the-deferred-anti-pattern); тем не менее, это избавляет вас от необходимости знать о '$ http' объекте от контроллера (т. е. вам не нужно знать данные, которые вы действительно хотите, это' response.data', а не только 'data') – Tom

+1

то, что вы обычно делаете, намного лучше и чище, я не вижу преимущества в том, чтобы идти на второй маршрут. '$ http' уже возвращает обещание, зачем создавать новый? – Nobita

+0

Вы добавляете разрешенное обещание к разрешенному обещанию, оно просто избыточно. $ q.defer() больше подходит для вещей, которые уже не имеют обещания. – ribsies

ответ

3

Нет, никаких преимуществ, это то же самое, в ваш первый код отрезала вы создали $q.defer() экземпляр, то вы вызвали его метод resolve() создать разрешенное обещание.

Это процесс, который вы должны знать и пройти бросок в angularJs при работе с асинхронно функциями и будущих объектов, которые будут иметь различные значения или новые данные в будущий момент, который вам нужен будет знать, когда это происходит, потому что заинтересованным сторонам вашего приложения может потребоваться получить доступ к отложенной задаче , когда она будет завершена.

Теперь при работе с $http вы не должны делать ничего из этого, потому что это будет уже возвращать решить обещание, что вы можете напрямую ссылаться на это then() метод, если у вас есть другой способ делать вещи, и вы должны применять другой подход.

Но не все сервисы angularJs собираются сделать для вас работу, посмотрите, например, $resource, который обертывает $http для использования в сценариях веб-API RESTful. $resource не возвращает разрешенное обещание, а обещание да, вы получаете один, но вам нужно сделать последний шаг его разрешения (check this stack question или this и возможно this article about Amber Kaplan's own experience working with Rest).

Итак, как вы это делаете, это хорошо, вот как я это делаю при работе с $http, но первый код фрагмента - это тот, который мы все будем искать, когда нам нужно будет что-то делать иначе с $http или заставлять другие услуги «работать с» или «работать как 'AJAX.

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