AngularJS:$q.dedefe()不能由工厂方法共享
AngularJS: the $q.defer() cannot be shared by factory methods
在我的webapp中,我编写了一个工厂方法,用于服务ajax调用并使用$q
服务返回promise。正如你可能知道的,我仍然在学习使用AngularJS;我在$q.dedefe()对象上发现了一些有趣的东西,它不能由工厂方法共享。我在工厂组件中编写了以下伪ajax调用(此处为plnker):
(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对象,否则它将无法工作所以我想知道为什么deferred
不能在工厂中的方法之间共享
为什么
deferred
不能在方法之间共享?
因为Deferred对象链接到它解析的promise。每个承诺都需要自己的承诺。如果您共享一个递延,每个方法都将返回相同的承诺。
另请参阅JavaScript中的Deferred、Promise和Future之间的区别是什么?。
实际上您可以共享延迟对象。不要把它看作一个服务,而是一个简单的JS对象。一个延迟对象只能解析一次,这是有目的的。在您的AjaxPromiseService中,您显然需要两个不同的延迟,因为您使用不同的数据来解决它们。
例如,$http.post()
每次返回不同的延迟对象
当您的延迟可以从不同的来源解决时,在多个函数之间共享一个延迟是有用的(例如,您试图同时从localStorage缓存、http源和一些计算这些数据的WebWorker中获取一些数据)
如果我理解正确,您希望重用$q.dedefer()创建的相同对象。
$q.delay()返回一个对象,该对象将在将来某个时候通过调用.resolve方法来解析。因此,基本上,它代表了一个将在未来某个时候完成的特定行动。
您不能为将来完成的多个操作共享同一个promise对象。另请参阅Bergi的anwser中的链接。
另外,你的plunker是坏的,因为
var methodObj = {getDummyData : getDummyData};
缺少getName,我在这个plunker 中修复了它
- 不能从angular2中的子组件指定父组件中的数组
- AngularJS UI路由器不能像ng路由器那样工作
- HTML5音频加载和播放获胜'我不能在iPad上工作
- 转义符不能与innerHTML一起使用
- JSON.parse没有'不能使用Javascript
- JS可以在Chrome中工作,但不能在Firefox中工作
- AngularJS:$q.dedefe()不能由工厂方法共享
- 可以从控制器更新工厂,但不能从指令更新
- 为什么我不能把服务注入到Angular的工厂/注入器中?
- Angular依赖注入——不能实例化工厂/未定义工厂
- AngularJS不能使用工厂在控制器之间共享数据
- angular JS不能在控制器中注入工厂
- 不能使用AngularJS工厂返回的数据
- 不能得到字符串.样机在工厂工作
- 工厂阵列只能被推入,不能被替换
- 工厂中的AngularJS函数不能从控制器中访问
- AngularJS工厂的$resource不能POST数据
- 承诺工厂不能在Nodejs中工作
- 不能模拟调用另一个工厂方法的工厂方法
- $watch不能与数据模型工厂一起工作