解析 - Javascript 嵌套调用

Parse - Javascript Nested Calls

我正在使用 Parse 编写 javascript 代码。我有 用户 class 和 订阅 class。所有用户的订阅信息都存储在 Subscription class 上,就像一对多的关系。

我想检索用户信息和每个用户的订阅数并将其存储在 object 数组中。

我试过的如下:

    var user = Parse.User;
    var query = new Parse.Query(user);
    query.find().then(function(objects) {
        return objects;
    }).then(function (objects) {

        for(var i = 0; i < objects.length; i++) {

            var object = objects[i];

            var subscription = Parse.Object.extend('Subscription');
            var queryForSubscription = new Parse.Query(subscription);
            queryForSubscription.equalTo('subscriptionUser', object);
            queryForSubscription.count().then(function(subscriptions) {

                var userEmail = object.get('email');
                var userDOB = object.get('userDOB');
                var userJoinedAt = object.createdAt;
                var userGender = object.get('userGender') ? 'Male' : 'Female';
                var subscriptionCount = subscriptions;

                var sub = [
                    userEmail,
                    userDOB,
                    userGender,
                    userJoinedAt,
                    subscriptionCount
                ];
                userArray.push(sub);
            });
        }
    });

但是,userArray 只重复包含最后一个用户的信息。我认为这是因为第二个查询承诺 (queryForSubscription).count()) 在外部 for 循环完成后运行。

假设我有用户 A 和用户 B。用户 A 有两个订阅,而用户 B 有 none。 我期望的是这样的:

    [{User A's email, User A's dob, User A's Gender, User A's Joined Date, 2},
    {User B's email, User B's dob, User B's Gender, User B's Joined Date, 0}]

然而,结果是

    [{User A's email, User A's dob, User A's Gender, User A's Joined Date, 2},
    {User A's email, User A's dob, User A's Gender, User A's Joined Date, 0}]

我现在卡住了。一直在尝试使用 Promise 等,但不知道..请帮忙!

更新

太爱了!!!非常感谢你们每一个人! 这里还有一个问题。实际上,我还有一个 class 叫做 Favourite 来计算每个用户的收藏数量。

如果用户A的收藏数是5,用户B的收藏数是3,最终的预期结果是这样的:

    [{User A's email, User A's dob, User A's Gender, User A's Joined Date, 2, 5},
    {User B's email, User B's dob, User B's Gender, User B's Joined Date, 0, 3}]

我不太确定我在哪里提出新的收藏夹查询 class...再次需要您的建议!

好像需要在执行最后一个函数的时候保存object的值。试试这个:

for(var i = 0; i < objects.length; i++) {

    var object = objects[i];

    queryForSubscription.count().then(
      (function(myObject){
        return function(subscriptions) {
            var userEmail = myObject.get('email');

            ...    

        };   
      })(object)
    );
}

你可以选择

另一种解决此错误的 hacky 方法是使用 .forEach() :

}).then(function (objects) {
    objects.forEach(function(object) {
        var subscription = Parse.Object.extend('Subscription');
        ...
    });
});

循环的每次迭代都会分配一个新的object变量,你应该避免"shared var"错误。


指出错误

一个常见的 javascript 陷阱是:局部变量的范围不是它最接近的 bloc,它是它最接近的 function.

以下片段:

function (objects) {
    for(var i = 0; i < objects.length; i++) {
        var object = objects[i];
        ...

实际上等同于:

function (objects) {
    var i, object;
    for(i = 0; i < objects.length; i++) {
        object = objects[i];
        ...

所以 OP 代码中的 object 变量实际上由所有创建的 queryForSubscription 变量共享,并且当执行任何 .then(..) 回调时(循环完成后,正如 OP 正确指出的那样),此 object 变量保存数组中最后一项的值。