javascript - 然后/ promises在for循环后不能使用变量

时间:2014-09-01 04:21:53

标签: javascript ajax parse-platform promise

我有这个代码,但是我无法在for循环之外使用这个userArray,不知道它为什么不返回任何内容,这里是代码:

Parse.Cloud.define("test", function(request, response) {

var UserFavourite = Parse.Object.extend("UserFavourite");
var queryFavourite = new Parse.Query(UserFavourite);

var userArray = [];
var TestItem = Parse.Object.extend("TestItem");
var query = new Parse.Query(TestItem);
query.limit(1000);
query.equalTo('school', 'Union College (NY)');
query.find().then(function(results) {
    return results;


}).then(function(results) {
    for (var i = 0; i < results.length; i++) { 
        var object = results[i];
        var item = object.get('item');
        var school = object.get('school');
        var meal = object.get('meal');

        var UserFavourite = Parse.Object.extend("UserFavourite");
        var queryFavourite = new Parse.Query(UserFavourite);
        queryFavourite.equalTo("item", item);
        queryFavourite.equalTo("school", school);
        queryFavourite.find().then(function(users) {
            for (var i = 0; i < users.length; i++) {
                var user = users[i];
                var userID = user.get('user').id;
                if (userArray.indexOf(userID) === -1) {
                    userArray.push(userID);
                }
//                  console.log(userArray);
                return userArray;
            }
            return userArray;


        });            
        console.log('sadf '+userArray);
    }
    console.log('sadf '+userArray);
    return userArray;


}).then(function() {
    console.log(userArray);
});

我已经看过这个但是我似乎仍然可以在最后一个函数中或在它之前的两个console.log中获取userArray

How do I return the response from an asynchronous call?

感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

注意:这不是经过测试的代码......但解决方案是使用一个承诺,一旦完成循环的所有承诺,将解决该承诺

var UserFavourite = Parse.Object.extend("UserFavourite");
var queryFavourite = new Parse.Query(UserFavourite);

var userArray = [];
var TestItem = Parse.Object.extend("TestItem");
var query = new Parse.Query(TestItem);
query.limit(1000);
query.equalTo('school', 'Union College (NY)');
query.find().then(function (results) {
    return results;
}).then(function (results) {
    var promises = [];
    for (var i = 0; i < results.length; i++) {
        var object = results[i];
        var item = object.get('item');
        var school = object.get('school');
        var meal = object.get('meal');

        var UserFavourite = Parse.Object.extend("UserFavourite");
        var queryFavourite = new Parse.Query(UserFavourite);
        queryFavourite.equalTo("item", item);
        queryFavourite.equalTo("school", school);
        var prom = queryFavourite.find().then(function (users) {
            for (var i = 0; i < users.length; i++) {
                var user = users[i];
                var userID = user.get('user').id;
                if (userArray.indexOf(userID) === -1) {
                    userArray.push(userID);
                }
                //                  console.log(userArray);
                return userArray;
            }
            return userArray;
        });
        promises.push(prom);
        console.log('sadf ' + userArray);
    }
    console.log('sadf ' + userArray);
    return Parse.Promise.when.apply(Parse.Promise, promises);
}).then(function () {
    console.log(userArray);
});

我们在这里做的是在循环中创建一个promises数组,它将被传递给.when()以返回一个promise,当所有传递给它的promise将被完成时,它将被解析。

因此,根据定义,最后then()应该获得更新的userArray - 测试并让我知道它是否有效

答案 1 :(得分:2)

APJ所说的似乎100%正确,但是通过避免不必要的分配以及array.map()array.reduce()的链接和合理使用,您可以大大降低代码量。

他们的眼睛适应array.map()array.reduce()的人甚至可能会发现可读性得到改善。

模式的核心是:

(new Parse.Query(...))...find().then(function(results) {
    return Parse.Promise.when(results.map(function(obj) { // map results to a new array, and return it.
        return (new Parse.Query(...))...find().then(function(users) {
            return users.map(...); // map users to a new array, and return it.
        });
    })).then(function() {// each argument to this function is an array of ids
        // process `arguments` to form a single array of unique ids, and return it.
    });
});

完整:

Parse.Cloud.define("test", function(request, response) {
    (new Parse.Query(Parse.Object.extend("TestItem")))
        .limit(1000)
        .equalTo('school', 'Union College (NY)')
        .find().then(function(results) {
            return Parse.Promise.when(results.map(function(obj) {
                return (new Parse.Query(Parse.Object.extend("UserFavourite")))
                    .equalTo("item", obj.get('item'))
                    .equalTo("school", obj.get('school'))
                    .find().then(function(users) {
                        return users.map(function(user) {
                            return user.get('user').id; // duplicates are filtered out below
                        });
                    });
            })).then(function() {
                return Array.prototype.slice.apply(arguments).reduce(function(p, c) { // reduce an array of arrays to a single array
                    return p.concat(c);
                }).filter(function(value, idx, self) { // filter out duplicates
                    return self.indexOf(value) === idx;
                });
            });
    }).then(function(userArray) { // named member `userArray` appears for the first time at this point
        console.dir(userArray);
    });
});

未测试

您将看到所需的数组不是直接合成的,而是从promises数组派生而来,每个promises都提供一组userID。

在性能方面,采用这种方法存在优缺点。没有测试,我就无法说出它会走哪条路。

答案 2 :(得分:0)

您需要更改此

then(function() {
            return Array.prototype.slice.apply(arguments).reduce(function(p, c) { // reduce an array of arrays to a single array
                return p.concat(c);
            }).filter(function(value, idx, self) { // filter out duplicates
                return self.indexOf(value22) === idx;
            });

then(function() {
            return Array.prototype.slice.apply(arguments).reduce(function(p, c) { // reduce an array of arrays to a single array
                return p.concat(c);
            }).filter(function(value, idx, self) { // filter out duplicates
                return self.indexOf(value2) === idx;
            });