【发布时间】:2016-09-23 10:28:39
【问题描述】:
大家好。我撞到了一堵砖墙。我正在尝试研究 Angular 异步方法调用、承诺对象并实现特定问题的解决方案。经过几个小时的反复试验和重组我的代码,我确信现在答案就在我的眼皮底下,但我看不到它。
我有一个场景,我必须使用 $http 进行后端服务调用,这会产生一个承诺。在 promise 的结果中,我将收到一个具有一个字符串属性和一个包含 100 个 ID 的数组的数据对象。这个后端服务一次只会传递 100 个 ID 的有效负载,所以我必须进行 x 次 $http 调用才能到达列表的末尾,正如这个后端服务所提供的那样。据我了解,我必须在 promise 的 .then() 方法中评估 $http 响应,如果字符串属性为“N”,那么我知道我必须再次调用后端服务以获取另一批 100 个 ID。在所有 ID 都已交付后,该字符串将包含一个“Y”,表示此结束已发送并且不再调用。不需要对这个计划发表评论,我知道它相当蹩脚,不幸的是我无法控制。 ;-)
如果需要更多的异步调用,我所研究的关于 Promise 的所有内容似乎都以线性方式说明了 Promise 的链接。无论承诺链是嵌套的还是扁平的,似乎我只能进行“已知”或固定数量的顺序调用,例如Promise1 到 Promise2,到 Promise3 等。请原谅我对这里的承诺的有限经验。
这是一个代码示例,你可以看到我卡在这里的地方,向下嵌套。我不能只是“希望”在打了 3 次、5 次或 10 次电话后我会得到所有的 ID。我需要动态评估每次调用的结果并再次调用。
这里是调用 $http 的 Angular 服务
(function() {
'use strict';
angular
.module('myapp')
.factory('IDservice', IDservice);
function IDservice($http) {
var service = {
model: {
error: {
state: false,
message: ''
},
ids: [],
end: '',
},
GetIDs: function() {
var request = 'some params...';
var url = 'the url...';
return $http.post(url, request).then(reqComplete).catch(reqFailed);
function reqComplete(response) {
service.model.ids = response.data.idList;
service.model.end = response.data.end;
return service.model;
}
function getIntradayMsrFailed(error) {
service.model.error.state = true;
service.model.error.message = error;
return service.model;
}
}
};
return service;
}
})();
这里是调用 Angular 服务的控制器,它最终在各个视图上驱动一些 UI 元素:
(function() {
'use strict';
angular
.module('myapp')
.controller('AvailableIDsController', AvailableIDsController);
function AvailableIDsController($scope, $location, $timeout, IDservice) {
var vm = this;
vm.completeIDList = [];
activate();
function activate() {
IDservice.GetIDs().then(function(response){
vm.completeIDList = response.ids;
console.log('promise1 end');
if(response.end === 'N'){
IDservice.GetIDs().then(function(response){
angular.forEach(response.ids,function(nextID){
vm.comleteIDList.push(nextID);
});
console.log('promise2 end');
if(response.end === 'N'){
IDservice.GetIDs().then(function(response){
angular.forEach(response.ids,function(nextID){
vm.comleteIDList.push(nextID);
});
console.log('promise3 end');
});
}
});
}
});
console.log('mainthread end');
}
}
})();
你可以看到它的去向......而且它非常非常丑陋。
我需要一种方法,在 activate() 方法中,调用一个方法,该方法将负责调用服务调用并将结果返回给 activate()。现在,仍然在 activate() 方法中,评估结果并确定是否再次调用,等等。我卡住的地方是一旦主处理线程完成,你就可以在第一个承诺中获得程序控制。从那里,您可以执行另一个承诺,等等,然后沿着兔子洞走。一旦我陷入这个陷阱,一切都将丢失。很明显我做的不对。我错过了其他一些简单的难题。任何建议将不胜感激!
【问题讨论】:
标签: javascript angularjs asynchronous promise angular-promise