gpt4 book ai didi

javascript - Angular $q promise 和非线性链接

转载 作者:行者123 更新时间:2023-11-30 15:49:02 25 4
gpt4 key购买 nike

大家好。我碰壁了。我正在尝试研究 Angular 异步方法调用、 promise 对象并针对特定问题实现解决方案。经过几个小时的反复试验和重组我的代码后,我确信此时答案就在我眼皮底下,但我看不到。

我有一个场景,我必须使用 $http 进行后端服务调用,这会产生一个 promise 。在 promise 的结果中,我将收到一个具有一个字符串属性和一个包含 100 个 ID 的数组的数据对象。此后端服务一次只能传送 100 个 ID 的有效负载,因此我必须进行 x 次 $http 调用才能到达列表末尾,正如此后端服务所提供的那样。据我了解 promise ,我必须评估 promise 的 .then() 方法中的 $http 响应,如果字符串属性为“N”,那么我知道我必须再次调用后端服务以获取另一批 100 个 ID。发送完所有 ID 后,该字符串将包含一个“Y”,表示发送结束,不要再调用。这个方案不需要评论,我知道它相当蹩脚,不幸的是我无法控制。 ;-)

如果需要更多的异步调用,我研究过的关于 promises 的所有内容似乎都以线性方式说明了 promises 链。无论 promise 链是嵌套的还是扁平的,似乎我只能进行“已知”或固定数量的顺序调用,例如Promise1 到 Promise2,再到 Promise3,等等。请原谅我在这里对 promise 的有限体验。

这是一个代码示例,您可以看到我卡在这里的地方,向下嵌套。我不能只是“希望”在 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 服务的 Controller,它最终在相应 View 上驱动一些 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() 方法中,评估结果并确定是否再次调用,等等。我被卡住的地方是一旦主处理线程完成,您将在第一个 promise 中留下程序控制。从那里,您可以执行另一个 promise ,等等,然后进入兔子洞。一旦我陷入这个陷阱,一切都会丢失。显然我没有做对。我错过了其他一些简单的拼图。任何建议将不胜感激!

最佳答案

您正在寻找普通的旧递归:

function AvailableIDsController($scope, $location, $timeout, IDservice) {
var vm = this;
vm.completeIDList = [];
return activate(0);

function activate(i) {
return IDservice.GetIDs().then(function(response) {
[].push.apply(vm.completeIDList, response.ids); // simpler than the loop
console.log('promise'+i+' end');
if (response.end === 'N'){
return activate(i+1);
}
});
}
}

不要忘记 return,这样 promise 就可以链接在一起,您可以等待请求结束。

关于javascript - Angular $q promise 和非线性链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39651511/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com