2015-04-09 7 views
0

В моем webapp я пишу заводские методы для обслуживания вызовов ajax и возврата обещаний с помощью службы $q. Как вы, наверное, можете сказать, я все еще нахожусь на кривой изучения использования AngularJS; Я нашел что-то интересное в объекте $ q.defer(), который не может использоваться общепринятыми методами. Я пишу следующий Ложные вызовы Ajax в заводском компоненте (plnker here):

(function() { 
    'use strict'; 

    angular.module('testAjax') 
    .factory('AjaxPromiseService', AjaxPromiseService); 

    AjaxPromiseService.$inject = ['$q', '$timeout']; 

    function AjaxPromiseService($q, $timeout) { 

    //var deferred = $q.defer(); //cannot be claimed for sharing here 

    var methodObj = {getDummyData : getDummyData, 
     getName: getName 
    }; 

    return methodObj; 

    /******************** implementations below **********/ 
    function getDummyData() { 
     var data = {"data" : "dummy data from ajax!"}; 
     var deferred = $q.defer(); 
     $timeout(function() { 
     deferred.resolve(data); 
     }, 3000); //3 seconds 

     return deferred.promise; 

    } //getDummyData 


    function getName() { 
     var deferred = $q.defer(); 
     $timeout(function() { 
     deferred.resolve({"name": "my name is john doe!"}); 
     }, 2000); //2 seconds 

     return deferred.promise; 
    } //getName 

    } 

}()); 

В моем контроллере, у меня есть следующий:

(function() { 
    'use strict'; 

    angular.module('testAjax', ['ui.router', 'Constants']) 
    .controller('testController', testController); 

    testController.$inject = ['$log', 'AjaxPromiseService', '$http', '$q', 'URL_CONFIGS']; 

    function testController($log, AjaxPromiseService, $http, $q, URL_CONFIGS) { 
    $log.info('in the testController'); 
    var vm = this; 
    vm.message = URL_CONFIGS.home; 

    vm.getData = function() { 

     AjaxPromiseService.getDummyData().then(function(data) { 
     vm.message += data.data; 
     //$log.info($q); 
     }).catch(function(err) { 
     $log.info('error in getting data'); 
     }).finally(function() { 
     $log.info('getData is completed'); 
     }); //getDummyData 

    }; //getData 


    vm.getName = function() { 
    AjaxPromiseService.getName().then(function(data) { 
     vm.message += data.name; 
     //$log.info($q); 
     }).catch(function(err) { 
     $log.info('error in getting data'); 
     }).finally(function() { 
     $log.info('getData is completed'); 
     }); //getDummyData 
}; //getName 

    } 
}()); 

В моем шаблоне, я следующие две кнопок которые вызывают две вышеуказанные функции в контроллере.

<button class="btn btn-primary" ng-click="contentView.getData()">Get data</button> 

    <button class="btn btn-primary" ng-click="contentView.getName()">Get name</button> 

    <strong>Message: {{contentView.message}}</strong> 

В заводском AjaxPromiseService составляющей, var deferred объект не может быть разделена между двумя функциями внутри завода, и я должен определить отложенный объект для каждой функции, в противном случае она не будет работать. Так что мне было интересно, почему deferred не могут быть использованы между методами на заводе?

ответ

3

Почему deferred нельзя использовать между методами?

Поскольку объект с отсрочкой связан с обещанием, которое он разрешает. Каждому обещанию нужен свой. Если вы разделите одно отложенное, каждый метод вернет то же обещание.

См. Также What are the differences between Deferred, Promise and Future in JavaScript?.

1

Фактически вы можете разделить отложенный объект. Просто подумайте об этом не как о службе, а о простом объекте JS. Один отложенный объект может быть разрешен только один раз, это сделано для цели. В вашем AjaxPromiseService вам, очевидно, нужны две разные отсрочки, потому что вы разрешаете их с разными данными.

, например, $http.post() каждый раз возвращаем различные отложенные объекты

обмен одной отложили между несколькими функциями полезно, если ваша отсрочка может быть разрешена из различных источников (например, вы пытаетесь получить некоторые данные одновременно из кэша LocalStorage, http source и некоторый WebWorker, который вычисляет эти данные)

1

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

$ q.defer() возвращает объект, который будет разрешен в какой-то момент в будущем, вызвав метод .resolve. Таким образом, в основном это представляет собой определенное действие, которое будет завершено в какой-то момент в будущем.

Вы не можете использовать один и тот же объект обещания для нескольких действий, которые будут завершены в будущем. См. Также ссылку в анкете Берги.

Также вы plunker раздирается

var methodObj = {getDummyData : getDummyData}; 

пропускает GetName я установил его in this plunker

+0

ваше понимание правильно. спасибо – TonyGW

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