我正在尝试实现$ q.all来运行一些函数,然后将所有输出返回到最后连接到.then的函数中 .
在承诺看起来他们正在以正确的顺序调用并且$ all . 然后在结束时发生,但结果变量返回一个空数组($ q.all中的每个承诺一个)
JS Fiddle可以在http://jsfiddle.net/QqKuk/120/找到,我正在使用角1.0.1
以下是我所拥有的代码的简化示例 .
这是我的html,只是在那里显示一些调试文本和输出 .
<div ng-controller="MyCtrl">
<p>{{fromThen}}</p>
<p>{{fromThen2}}</p>
<p>{{runOrder}}</p>
</div>
这是我的控制器,实际上logOne,logTwo和logThree不会是相同的功能 .
var myApp = angular.module('myApp',[]);
function MyCtrl($ scope,$ q,$ timeout){
var logOne = function (value) {
$scope.fromThen = $scope.fromThen + value;
var deffered = $q.defer();
deffered.promise.then( function() {
$scope.runOrder = $scope.runOrder + '.logOne()';
$scope.fromThen = $scope.fromThen + value.toUpperCase();
deffered.resolve(value);
return deffered.promise;
});
deffered.resolve();
};
var logTwo = function (value) {
$scope.fromThen = $scope.fromThen + value;
var deffered = $q.defer();
deffered.promise.then( function() {
$scope.runOrder = $scope.runOrder + '.logTwo()';
$scope.fromThen = $scope.fromThen + value.toUpperCase();
deffered.resolve(value);
return deffered.promise;
});
deffered.resolve();
};
var logThree = function (value) {
$scope.fromThen = $scope.fromThen + value;
var deffered = $q.defer();
deffered.promise.then( function() {
$scope.runOrder = $scope.runOrder + '.logThree()';
$scope.fromThen = $scope.fromThen + value.toUpperCase();
deffered.resolve(value);
return deffered.promise;
});
deffered.resolve();
};
$scope.fromThen = '';
$scope.fromThen2 = 'No Value';
$scope.runOrder = '';
$q.all([logOne('One'), logTwo('Two'), logThree('Three')])
.then(function(results) {
$scope.runOrder = $scope.runOrder + '.then';
$scope.fromThen2 = results;
});
}
我得到的输出是
OneTwoThreeONETWOTHREE [null,null,null] .logOne() . logTwo() . logThree() . 然后
对我来说,看起来事情正在以正确的顺序调用,所以我很困惑为什么我在返回值中得到空值 . 我是否错误地使用了defer.resolve(value)?
我在这里看了一些其他的例子,但是我还没弄清楚为什么我没有得到结果 .
谢谢你提供的所有帮助 . 由于这也是我的第一篇文章,任何关于我应该包括(或不需要包括)的信息的提示也将不胜感激 .
谢谢 . 尼尔
1 回答
您的问题是,您没有从日志功能本身返回您的承诺,以便跟随
$q.all
. 你're resolving the promises and returning them somewhere, but not to anywhere that'正在听 . 调用.then
内部的函数由$q
调用,返回值被发送到promises.then
本身返回的解析回调 . 您有希望的功能应采取以下形式:另外
在你的情况下,当你
doSomethingDeferredWith(data)
你:这个特定的操作并不需要延迟,它会立即完成,但是如果你查询基于
$http
的服务,那么你将得到你的deferredMore
承诺:然后,在're done doing that, you'之后,将某个结果作为参数传递给
.then
的.then
调用中引用的函数,就像从doSomethingDeferredWith
返回的那样:现在,由于
$q
的工作方式,对doSomethingDeferredWith(data)
的调用返回一个promise,.then
在该promise上调用,传入的函数排队, but is not executed until the current script loop ends . 这意味着调用.then
,函数排队,然后doSomethingDeferred
继续执行,返回,然后其调用函数继续执行,直到调用堆栈清除为止 . 只有在那之后$q
才有机会回来并运行已解决的承诺的所有回调 .在你的代码
doSomethingDeferred
中,各种log***
函数实际上并没有返回一个promise . 他们返回undefined
. 如果您返回我们创建的承诺,并且当$q
运行回调而不是doSomethingDeferred
结束时将解析,您将在$q.all
的回调中获取数据 .要修复代码,请将每个日志文件末尾的
deffered.resolve();
调用更改为return deffered.promise;
然后,日志函数的返回值将不是undefined
,它们将是$q
可以遵循的承诺,并在所有日志上运行回调在完成所有三次调用后,他们的三个.resolve
调用立即调用,将$scope.runFrom2
值设置为['One','Two','Three']
数组,因为每个单独的承诺都会通过延迟函数的闭包框架中的value
解析 .