简体   繁体   English

for循环中的Javascript承诺角​​链

[英]Javascript angular chain of promises in for loop

I would like that the for loop will be executed and then the result will be sent over the next function: 我希望将执行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))
    })
})

the FindIdsRequests function should return the result of the for loop however there is no return (the alert is not printed so does not arrive there). FindIdsRequests函数应该返回for循环的结果,但是没有返回(警报没有打印出来,所以没有到达那里)。 Any idea? 任何想法?

You can take advantages of $q insted of returning a promise like so: 您可以利用$q优点来返回承诺,如下所示:

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

For example: 例如:

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;
    });
}

This code will return a promisse of all promisses in the array to be resolved. 此代码将返回要解决的数组中所有许可的许可。

Problems: 问题:

  1. You are overwriting promise in each iteration of loop... so there is only ever one promise 您将要覆盖promise在每个循环迭代...所以永远只能一个promise
  2. There is no resolve of promise to ever trigger then() so the array will always be empty 永远无法触发then()的诺言解析,因此数组将始终为空
  3. You have a return in the loop so the loop will break on first iteration and never complete 您在循环中有return ,因此循环将在第一次迭代时中断并且永远不会完成
  4. If this were asynchronous i will not be what you think it is inside then() as it will have reached it's end before the promise resolves 如果这是异步i不会是你认为它是内部then()因为它会已承诺结算前,达到它的结束

I see no need to write this up in code since everything you are doing is synchronous and shows no need for promise in the first place 我认为无需在代码中编写代码,因为您所做的一切都是同步的,并且一开始就不需要承诺

Ok thanks also to the comments of @charlietlf the following code works: 好的,还要感谢@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
     })
}

essentially I forgot to put the resolve. 本质上,我忘了下决心了。

Creating a Chain of Promises from an Array of Promises 从一系列承诺中创建承诺链

Use $.when to create an empty promise and use a for loop to create a chain: 在创建空承诺时使用$.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;
};

The above example starts with an empty promise, then chains from that empty promise. 上面的示例以一个空的承诺开始,然后从该空的承诺中进行链接。 The final promise will resolve to the array created by the chain. 最终的承诺将解决链所创建的数组。

Chaining promises 连锁承诺

Because calling the .then method of a promise returns a new derived promise, it is easily possible to create a chain of promises. 因为调用promise的.then方法会返回新的派生promise,所以很容易创建promise的链。 It is possible to create chains of any length and since a promise can be resolved with another promise (which will defer its resolution further), it is possible to pause/defer resolution of the promises at any point in the chain. 可以创建任何长度的链,并且由于一个承诺可以用另一个承诺来解决(这将进一步推迟其解决方案),因此可以在链中的任何点暂停/推迟对承诺的解决。 This makes it possible to implement powerful APIs. 这样就可以实现功能强大的API。

-- AngularJS $q Service API Reference -- chaining promises -AngularJS $ q服务API参考-链接承诺

The example executes the promises sequentially. 该示例按顺序执行promise。 To execute the promises in parallel use the $q.all method . 要并行执行承诺,请使用$ q.all方法

Your FindIdsRequests() function has no async elements in the code as shown so it can just be a synchronous function and, in fact, trying to use promises in it is just complicating a very simple operation: 如图所示,您的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