簡體   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