简体   繁体   English

AngularJS $ q.all()结果为null

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

I'm trying to implement a $q.all to run some functions and then return all the outputs into a function attached to the .then at the end. 我正在尝试实现$ q.all来运行一些函数,然后将所有输出返回到最后附加到.then的函数中。

At the moment the promises look like they're calling in the correct order and the $all .then is occurring at the end, but the results variable comes back with an array of nulls (one for each promise in the $q.all) 在承诺看起来他们正在以正确的顺序调用并且$ all .then在最后发生,但结果变量返回一个空数组($ q.all中的每个承诺一个)

JS Fiddle can be found at http://jsfiddle.net/QqKuk/120/ and I'm using angular 1.0.1 JS Fiddle可以在http://jsfiddle.net/QqKuk/120/找到,我使用的是角1.0.1

The below is a simplified example of the code I have. 以下是我所拥有的代码的简化示例。

Here is my html, simply just there to display some debug text and the output. 这是我的html,只是在那里显示一些调试文本和输出。

<div ng-controller="MyCtrl">
    <p>{{fromThen}}</p>
    <p>{{fromThen2}}</p>
    <p>{{runOrder}}</p>
</div>

and here is my controller, in reality logOne, logTwo, and logThree aren't going to be identical functions. 这是我的控制器,实际上logOne,logTwo和logThree不会是相同的功能。

var myApp = angular.module('myApp', []); var myApp = angular.module('myApp',[]);

function MyCtrl($scope, $q, $timeout) { 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;
                    });

}

The output I'm getting is 我得到的输出是

OneTwoThreeONETWOTHREE [null,null,null] .logOne().logTwo().logThree().then OneTwoThreeONETWOTHREE [null,null,null] .logOne()。logTwo()。logThree()。​​then

Which to me looks like things are calling in the correct order, so I'm confused why I'm getting nulls in the return value. 对我来说,事情看起来是正确的顺序调用,所以我很困惑为什么我在返回值中得到空值。 Am I using the defer.resolve(value) incorrectly? 我是否错误地使用了defer.resolve(value)?

I've looked at some of the other examples on here but I haven't been able to work out why I'm not getting a result. 我在这里看了一些其他的例子,但是我还没弄清楚为什么我没有得到结果。

Thanks for any help you can give. 谢谢你提供的所有帮助。 Since this is also my first post, any tips on what information i should also include (or didn't need to include) would also be appreciated. 由于这也是我的第一篇文章,任何有关我应该包括(或不需要包括)的信息的提示也将不胜感激。

Thanks. 谢谢。 Neil 尼尔

Your issue is that you're not returning your promises from the log functions themselves for $q.all to follow. 您的问题是,您没有从日志功能本身返回您的承诺,以便$q.all跟随。 You're resolving the promises and returning them somewhere, but not to anywhere that's listening. 你正在解决这些承诺并将它们归还给某个地方,但不是在任何正在倾听的地方。 Functions inside calls to .then are called by $q and the return values are sent to the resolution callbacks for the promises .then itself returns. 函数中调用.then由被称为$q和返回值被发送到了承诺的决议回调.then自己返回。 Your promising functions should take the form: 您有希望的功能应采取以下形式:

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

Alternatively 另外

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

In your case, when you doSomethingDeferredWith(data) you: 在您的情况下,当您执行doSomethingDeferredWith(data)时:

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

This particular action doesn't really need to be deferred, it finishes immediately, but if you were querying an $http based service, then you'd get your deferredMore promise back: 这个特定的操作并不需要延迟,它会立即完成,但是如果你查询的是基于$http的服务,那么你将获得deferredMore承诺:

  return deferredMore.promise;
}

Then, after you're done doing that, you're going to get some result as a parameter to a function referenced in a call to .then on a promise like the one returned from doSomethingDeferredWith : 然后,在你完成这项工作之后,你将获得一些结果作为参数,这个参数是在一个类似于doSomethingDeferredWith返回的promise类的.then调用中引用的函数:

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

Now, because of the way $q works, the call to doSomethingDeferredWith(data) returns a promise, .then is called on that promise and the function passed in is queued up, but is not executed until the current script loop ends . 现在,因为该方式$q作品,调用doSomethingDeferredWith(data)返回一个承诺, .then叫上承诺,在排队,传递的功能, 但直到当前的脚本结束循环不执行 This means that .then is called, the function is queued, and then doSomethingDeferred continues executing, returns, and its calling function then continues executing until the call stack has cleared. 这意味着.then被调用,函数排队,然后doSomethingDeferred继续执行,返回,然后它的调用函数继续执行,直到调用堆栈清除。 Only after that does $q have the opportunity to come back and run all of the callbacks for resolved promises. 只有在那之后, $q才有机会回来并运行已解决的承诺的所有回调。

In your code, doSomethingDeferred , the various log*** functions, do not actually return a promise. 在你的代码中, doSomethingDeferred ,各种log***函数,实际上并没有返回一个promise。 They return undefined . 他们返回undefined If you instead return the promise we created and will resolve when $q runs the callback instead of at the end of doSomethingDeferred , you'll get your data in the callback for $q.all . 如果您改为返回我们创建的promise,并且当$q运行回调而不是doSomethingDeferred结束时将解析,您将在$q.all的回调中获取数据。

To fix your code, change the deffered.resolve(); 要修复代码,请更改deffered.resolve(); calls at the end of each of your log files to return deffered.promise; 在每个日志文件的末尾调用以return deffered.promise; Then, the return values for the log functions won't be undefined , they'll be promises that $q can follow and run a callback on all three of their .resolve calls at once after all three calls are made, setting your $scope.runFrom2 value to an array of ['One','Two','Three'] as each individual promise resolves with the value from the closure frame of the deferring function. 然后,日志函数的返回值将不会被undefined ,它们将是$q可以遵循的承诺,并且在完成所有三个调用之后立即对所有三个.resolve调用运行回调,设置$scope.runFrom2值为['One','Two','Three']数组,因为每个单独的promise都使用deferring函数的闭包框架中的value解析。

tl;dr Version tl;博士版

Change the deffered.resolve(); 更改deffered.resolve(); calls at the end of each of your log files to return deffered.promise; 在每个日志文件的末尾调用以return deffered.promise;

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

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