AngularJS $ q.all()结果为空

我试图执行一个$ q.all来运行一些函数,然后将所有输出返回到最后附加到.then的函数中。

目前承诺看起来像是按照正确的顺序调用,并且$ all .then发生在最后,但结果变量带有一组空值(在$ q.all中的每个promise都有一个)

JS小提琴可以在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',[]);

函数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调用,返回值被发送到promise的解析回调函数.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;
}

然后,在完成之后,您将获得一些结果作为调用to的一个函数的参数.then然后像doSomethingDeferredWith返回的那样promise

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

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

在你的代码中, doSomethingDeferred ,各种log***函数并不实际返回一个承诺。 他们返回undefined 。 如果您返回我们创建的承诺,并在$q运行回调而不是doSomethingDeferred结束时解决,您将在$q.all的回调中获得数据。

要修复您的代码,请更改deffered.resolve(); 调用每个日志文件的结尾以return deffered.promise; 然后,日志函数的返回值不会是undefined ,它们将是$q可以跟随的承诺,并且在所有三次调用完成后立即对其全部三个.resolve调用执行回调,从而设置$scope.runFrom2值赋给一个['One','Two','Three']的数组,因为每个单独的promise使用来自延迟函数的闭包帧的value来解析。

tl; dr版本

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

链接地址: http://www.djcxy.com/p/95231.html

上一篇: AngularJS $q.all() results are null

下一篇: angularJS: wait for template to be evaluated before directive loads