我想使用$ q.all来等待函数完成。我在plunker http://plnkr.co/edit/uG2JujPqoiBgqtRjEZwh?p=preview
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.28/angular.min.js"></script>
</head>
<body ng-app="App">
<div ng-controller="AppController">
Its the app
<button ng-click="run()">Run (check console)</button>
</div>
<script>
var App = angular.module("App", []);
App.controller("AppController", function($scope,$q){
$scope.xxy = function(num){
var d = $q.defer();
for(var i=0;i<100000;i++){
//do nohing
}
d.resolve(num*20);
var promise = d.promise;
return $q.all([promise]).then(function(data){
return data;
});
};
$scope.run = function(){
for(var i=0;i<10;i++){
console.log(i);
console.log($scope.xxy(i));
//$scope.xxy(i).then(function(r){
// console.log(r);
//})
}
};
});
</script>
</body>
</html>
函数 xxy()是以 async 方式编写的,但我希望它使用$ q 同步。所有。不能改变xxy函数的性质,因为它会破坏我的大项目中的其他东西。 xxy()是我正在使用的一个大函数的简单版本,并使用$ q.defer构建它。
所以基本上我希望输出为:1 20 2 40 ...而不是当前的1 2 .. 20 40 ......
答案 0 :(得分:1)
问题在于你的跑步功能....你现在已经注释掉了....
$scope.xxy(i).then(function(r){
console.log(r);
})
但$ q.all解析了一系列结果(按照承诺的传递顺序排列,所以你需要使用它...
$scope.xxy(i).then(function(r){
console.log(r[0]); // first item of the result array
})
编辑此处处于更新的plnkr
来自文档(link) 将多个promise组合成一个promise,在解析所有输入promise时解析。 返回:承诺的数组或散列。
答案 1 :(得分:1)
所以,你想要序列化行为:打印1,调用异步函数并打印返回值20,然后再次运行循环,打印2,然后调用异步函数,依此类推?
这确实是一个有趣的问题。对我而言,您似乎需要使用repeater pattern。
适用于您的案件:
App.controller("AppController", function($scope,$q,$timeout) {
$scope.xxy = function(num) {
var d = $q.defer();
$timeout(function() {
d.resolve(num*20);
}, 1000);
return d.promise;
};
$scope.repeater = function(i) {
if (i < 10) {
console.log(i);
$scope.xxy(i).then(function(ret) {
console.log(ret);
$scope.repeater(i + 1);
});
}
};
$scope.run = function() {
$scope.repeater(0);
};
});
请参阅操作:JSFiddle。
我添加$timeout
来演示异步行为,并能够将承诺解析为它所属的回调。
我希望我能正确理解你的问题。
答案 2 :(得分:0)
$scope.xxy(i)
会返回承诺。
您无法循环并等待返回值。承诺不会那样工作。
相反,你必须这样做。
$scope.xxy(num).then(function(value){
...
});
$q.all(..)
将数组中的所有承诺包装成新的承诺。