簡體   English   中英

for循環中的Javascript承諾角​​鏈

[英]Javascript angular chain of promises in for loop

我希望將執行for循環,然后將結果通過下一個函數發送:

FindIdsRequests =  function(){
    results = $scope.requests
    var deferred = $q.defer();
    var promise = deferred.promise;
    var array = []
    for (var i in results) {
        promise = promise.then(function(){
            array.push(results[i].uid)      
        })
        return promise
    }
    return promise.then(function(){
        return array
    })
}

$scope.ConfirmRequests = function(){
    //alert('req'+JSON.stringify($scope.requests))
    FindIdsRequests().then(function(array){
        alert('arr'+JSON.stringify(array))
    })
})

FindIdsRequests函數應該返回for循環的結果,但是沒有返回(警報沒有打印出來,所以沒有到達那里)。 任何想法?

您可以利用$q優點來返回承諾,如下所示:

$q.all([promise1, promise2]);

例如:

FindIdsRequests =  function(){

    var requests = $scope.requests;
    var results = [];    
    var array = [];

    for (var i in requests) {

        var req = $http.get('http://someUrl.com/' + requests[i].uid);

        array.push(req);

        req.then(function (response) {
            results.push(response.data);
        });
    }

    return $q.all(array).then(function(){
        return results;
    });
}

此代碼將返回要解決的數組中所有許可的許可。

問題:

  1. 您將要覆蓋promise在每個循環迭代...所以永遠只能一個promise
  2. 永遠無法觸發then()的諾言解析,因此數組將始終為空
  3. 您在循環中有return ,因此循環將在第一次迭代時中斷並且永遠不會完成
  4. 如果這是異步i不會是你認為它是內部then()因為它會已承諾結算前,達到它的結束

我認為無需在代碼中編寫代碼,因為您所做的一切都是同步的,並且一開始就不需要承諾

好的,還要感謝@charlietlf的注釋,以下代碼有效:

FindIdsRequests =  function(){

    results = $scope.requests
    var deferred = $q.defer();
    var promise = deferred.promise;
    var array = []
    for (var i in results) {
        alert('www'+JSON.stringify(results[i].uid))
        var obj = results[i].uid
        promise = promise.then(function(){
            array.push(results[i].uid)      
        })
        //return promise
    }
    deferred.resolve(array)
    return promise.then(function(){
            alert('ee'+JSON.stringify(array))
            return array
     })
}

本質上,我忘了下決心了。

從一系列承諾中創建承諾鏈

在創建空承諾時使用$.when ,並使用for循環創建鏈:

function chainPromiseArray(promiseArray){
    var promise = $q.when();
    var array = [];
    for (var i=0;  i < promiseArray.length; i++) {
        promise = promise.then(function(){
            var derivedPromise = promiseArray[i].then(function(result) {
                //push data
                array.push(result.data);
            });
            //return promise to chain
            return derivedPromise;
        });
    };
    var finalPromise =  promise.then(function(){
        return array;
    });
    return finalPromise;
};

上面的示例以一個空的承諾開始,然后從該空的承諾中進行鏈接。 最終的承諾將解決鏈所創建的數組。

連鎖承諾

因為調用promise的.then方法會返回新的派生promise,所以很容易創建promise的鏈。 可以創建任何長度的鏈,並且由於一個承諾可以用另一個承諾來解決(這將進一步推遲其解決方案),因此可以在鏈中的任何點暫停/推遲對承諾的解決。 這樣就可以實現功能強大的API。

-AngularJS $ q服務API參考-鏈接承諾

該示例按順序執行promise。 要並行執行承諾,請使用$ q.all方法

如圖所示,您的FindIdsRequests()函數在代碼中沒有異步元素,因此它可以只是一個同步函數,實際上,嘗試在其中使用Promise只是使一個非常簡單的操作變得復雜:

// get an array of uid from $scope.requests
function FindIdsRequests() {
    return $scope.requests.map(function(item) {
        return item.uid;
    });
});

$scope.ConfirmRequests = function() {
    var ids = FindIdsRequests();
    console.log('arr: '+ JSON.stringify(ids));
})

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM