繁体   English   中英

AngularJS $ q.all()结果为null

[英]AngularJS $q.all() results are null

我正在尝试实现$ q.all来运行一些函数,然后将所有输出返回到最后附加到.then的函数中。

在承诺看起来他们正在以正确的顺序调用并且$ all .then在最后发生,但结果变量返回一个空数组($ 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()。​​then

对我来说,事情看起来是正确的顺序调用,所以我很困惑为什么我在返回值中得到空值。 我是否错误地使用了defer.resolve(value)?

我在这里看了一些其他的例子,但是我还没弄清楚为什么我没有得到结果。

谢谢你提供的所有帮助。 由于这也是我的第一篇文章,任何有关我应该包括(或不需要包括)的信息的提示也将不胜感激。

谢谢。 尼尔

您的问题是,您没有从日志功能本身返回您的承诺,以便$q.all跟随。 你正在解决这些承诺并将它们归还给某个地方,但不是在任何正在倾听的地方。 函数中调用.then由被称为$q和返回值被发送到了承诺的决议回调.then自己返回。 您有希望的功能应采取以下形式:

var function = doSomthingDeferred(data) {
  var deferred = $q.defer();
  doSomethingDeferredWith(data).then(function(deferredResult) {
    var processedResult = processDeferredResult(deferredResult);
    deferred.resolve(processedResult);
  });
  return deferred.promise;
}

另外

var function = doSomthingDeferred(data) {
  return doSomethingDeferredWith(data).then(function(deferredResult) {
    var processedResult = processDeferredResult(deferredResult);
    return processedResult;
  });
}

在您的情况下,当您执行doSomethingDeferredWith(data)时:

function doSomethingDeferredWith(data) {
  var deferredMore = $q.defer();
  $scope.fromThen += data;
  deferredMore.resolve($scope.fromThen);

这个特定的操作并不需要延迟,它会立即完成,但是如果你查询的是基于$http的服务,那么你将获得deferredMore承诺:

  return deferredMore.promise;
}

然后,在你完成这项工作之后,你将获得一些结果作为参数,这个参数是在一个类似于doSomethingDeferredWith返回的promise类的.then调用中引用的函数:

doSomethingDeferredWith(data).then(function(deferredResult) {

现在,因为该方式$q作品,调用doSomethingDeferredWith(data)返回一个承诺, .then叫上承诺,在排队,传递的功能, 但直到当前的脚本结束循环不执行 这意味着.then被调用,函数排队,然后doSomethingDeferred继续执行,返回,然后它的调用函数继续执行,直到调用堆栈清除。 只有在那之后, $q才有机会回来并运行已解决的承诺的所有回调。

在你的代码中, doSomethingDeferred ,各种log***函数,实际上并没有返回一个promise。 他们返回undefined 如果您改为返回我们创建的promise,并且当$q运行回调而不是doSomethingDeferred结束时将解析,您将在$q.all的回调中获取数据。

要修复代码,请更改deffered.resolve(); 在每个日志文件的末尾调用以return deffered.promise; 然后,日志函数的返回值将不会被undefined ,它们将是$q可以遵循的承诺,并且在完成所有三个调用之后立即对所有三个.resolve调用运行回调,设置$scope.runFrom2值为['One','Two','Three']数组,因为每个单独的promise都使用deferring函数的闭包框架中的value解析。

tl;博士版

更改deffered.resolve(); 在每个日志文件的末尾调用以return deffered.promise;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM