javascript - 在for循环结束时调用promises

时间:2014-09-02 22:21:08

标签: javascript arrays parse-platform cloud promise

我有这段代码,我想让代码等到调用prom的异步查询在重新启动第一个for循环之前已经过了。因此,在重新启动第一个for循环之前,数组将被重置。

items = [];
var promises = [];
    for (var i = 0; i < userArray.length; i++) {

        items.length = 0;
        for (var i2 = 0; i2 < test.length; i2++) {

            var UserFavourite = Parse.Object.extend("UserFavourite");
            var queryUserFav = new Parse.Query(UserFavourite);
            queryUserFav.equalTo('item', test[i2].get('item'));
            queryUserFav.equalTo('school', test[i2].get('school'));
            queryUserFav.equalTo('user1', userArray[i])
            var prom = queryUserFav.find().then(function(res) {


                    for (var i3 = 0; i3 < res.length; i3++){
                        var item = res[i3];
                        var itemName = item.get('item');
                        items.push(itemName);
                        console.log(items)

                    }
                    return items;


            });
            promises.push(prom);

        }
        //return Parse.Promise.when.apply(Parse.Promise, promises); I have tried it here but
        // this just stops the first for loop after its first loop

    }
    return Parse.Promise.when.apply(Parse.Promise, promises);

3 个答案:

答案 0 :(得分:0)

你要做的是拥有一系列承诺,一个数组中的每个项目都有一个承诺。

如果javascript具有相同的.NET await关键字,那么你可以去哪里

 await Parse.Promise.when(promises)

然后它允许promise代码运行,然后返回到await之后运行任何代码。但Javascript并没有向我们提供此信息。


另一种方法是维护index变量。处理完每组查询后,您可以递增index变量并处理下一组值。

 function parseForUser(user) {
      var promises = [];
      for (var i2 = 0; i2 < test.length; i2++) {
        var items = [];
        var UserFavourite = Parse.Object.extend("UserFavourite");
        var queryUserFav = new Parse.Query(UserFavourite);
        queryUserFav.equalTo('item', test[i2].get('item'));
        queryUserFav.equalTo('school', test[i2].get('school'));
        queryUserFav.equalTo('user1', user)
        var prom = queryUserFav.find().then(function(res) {
                for (var i3 = 0; i3 < res.length; i3++){
                    var item = res[i3];
                    var itemName = item.get('item');
                    items.push(itemName);
                    console.log(items)

                }
                return items;
        });
        promises.push(prom);
      }
      return Parse.Promise.when(promises);

 }


 function parseUserArray(userArray) {
     var returnPromise = new Parse.Promise(); // Do you have to call it via new? 
                                              //The documentation isn't clear.
     var index = 0;
     var doNext = function() {
         if(index < userArray.length) {
            var promise = parseForUser(userArray[index++]);
            promise.done(doNext);
         } else {
             returnPromise.resolve(); 
         }
     }
     doNext();
     return returnPromise;
 }

 var parseUserArrayPromise = parseUserArray(userArray);

答案 1 :(得分:0)

FWIW ......

这个解决方案与@ AndrewShepherd的主要区别在于,我们在这里采用asyncProcessUser()返回的承诺的双重优势。

  • 首先进行流量控制 - 内循环的异步排序
  • 其次是提供一系列结果,从中构建最终的结果数组,避免使用外部promises数组。
function parseUserArray(userArray, test) {

    // This function is the original inner for() loop, now expressed as a .map(), 
    // (plus peripheral wrapping and chaining).
    // It asynchronously processes a single user against all test items,
    // and returns a promise of an array of results.
    // The promise resolves when all the individual .finds complete.
    function asyncProcessUser(user) {
        return Parse.Promise.when(test.map(function(dataItem) {
            return (new Parse.Query(Parse.Object.extend("UserFavourite")))
                .equalTo('item', dataItem.get('item'))
                .equalTo('school', dataItem.get('school'))
                .equalTo('user1', user)
                .find().then(function(res) {
                    return res.map(function(r) {
                        return r.get('item');
                    });
                });
        })).then(function() {
            return Array.prototype.slice.apply(arguments).reduce(function(arr, arr_) {
                return arr.concat(arr_);
            }, []);
        });
    }

    // This is the original outer for() loop, now expressed as a .reduce(), which is 
    // a common pattern for performing a series of async tasks (ie what was the inner loop).
    // Here, `userArray.reduce(...)` returns a promise of an array of 
    // the objects returned by `r.get('item')` above.
    return userArray.reduce( function(p, user) {
        return p.then(function(arr) {
            return asyncProcessUser(user).then(function(arr_) {
                return arr.concat(arr_);
            });
        });
    }, Parse.Promise.as([]) );//† "returns a new promise that is resolved with a given value".
}

†:Documentation for Parse.Promise.as()

没有评论,它就非常简洁。

概念演示 here 。不要担心演示使用jQuery承诺,这是重要的概念。

答案 2 :(得分:-1)

使用此

function parseForUser(user) {
      var promises = [];
      for (var i2 = 0; i2 < test.length; i2++) {
        var items = [];
        var UserFavourite = Parse.Object.extend("UserFavourite");
        var queryUserFav = new Parse.Query(UserFavourite);
        queryUserFav.equalTo('item', test[i2].get('item'));
        queryUserFav.equalTo('school', test[i2].get('school'));
        queryUserFav.equalTo('user1', user)
        var prom = queryUserFav.find().then(function(res) {
                for (var i3 = 0; i3 < res.length; i3++){
                    var item = res[i3];
                    var itemName = item.get('item');
                    items.push(itemName);
                    console.log(items)

                }
                return items;
        });
        promises.push(prom);
      }
      return Parse.Promise.when(promises);

 }


 function parseUserArray(userArray) {
     var returnPromise = new Parse.Promise(); // Do you have to call it via new? 
                                              //The documentation isn't clear.
     var index = 0;
     var doNext = function() {
         if(index < userArray.length) {
            var promise = parseForUser(userArray[index++]);
            promise.done(doNext);
         } else {
             returnPromise.resolve(); 
         }
     }
     doNext();
     return returnPromise;
 }

只需复制并粘贴

即可