解析:从云代码更新对象

Parse: Update Object from Cloud Code

我每分钟创建一个 运行 后台作业。它的目的是删除数据库中的旧数据或过时数据。在这种情况下,用户提交了一个附加时间戳的时间,这两个值存储在数组 timestimestamp 中。所以我写了我的云代码来通过时间戳检查时间是否早于一个小时。如果是这样,请将它们从数据库中删除。但是,那是我遇到麻烦的部分。这是我的云代码,因此您可以看到发生了什么:

Parse.Cloud.job("expireTimes", function(request, response){
Parse.Cloud.useMasterKey();
var currentTime = new Date().getTime() / 1000;
var query = new Parse.Query("Wait");
query.find().then(function(results) {
    var times = (results.length>0)? results[0].get("times") : "n/a";
    var timestamps = (results.length>0)? results[0].get("timestamp") : "n/a";
    console.log("Got " + results.length + " Times: " + times);
    console.log("Got " + results.length + " Timestamps: " + timestamps);
    for (var i = 0; i < timestamps.length; i++) {
        if (currentTime >= timestamps[i] + 3600) {
            // Delete old wait times
            timestamps.splice(i, 1);
            times.splice(i, 1);
            i--;
        } else {
            break;
        }
    };

    response.success("success");
}, function(error) {
    response.error(error);
});
})

如何更新数据库并删除数组中的值。因为当用户提交的时候,它只是添加到 times 数组中。好吧,如果我每分钟都在进行后台作业,那么某些条目不会超过一个小时。我想保留那些,但去掉其他的。

有什么想法吗?任何帮助深表感谢。 谢谢

答案的本质部分是可以使用 set() 设置对象属性,并使用 save() 保存对象。这是一个简单的例子......

    // say object is some object that's been retrieved from the database
    var times = object.get("times");
    var timestamps = object.get("timestamp");  // would be better to make the array name plural in the database

    // do whatever you want to the arrays here, then ...

    object.set("times", times);
    object.set("timestamp", timestamps);
    return results[0].save();
}).then(function(result) {
        response.success("success");
}, function(error) {
        response.error(error);
});

但我知道您确实想为许多 Wait 对象执行此操作,因此我们需要更强大的设计。让我们开始养成构建执行逻辑工作块的函数的习惯。这是为给定的 Wait 对象修复这些数组的方法...

// delete parts of the waitObject time arrays prior to currentTime
function removeOldWaitTimes(waitObject, currentTime) {
    var times = waitObject.get("times");
    var timestamps = waitObject.get("timestamp");
    for (var i = 0; i < timestamps.length; i++) {
        if (currentTime >= timestamps[i] + 3600) {
            // Delete old wait times
            timestamps.splice(i, 1);
            times.splice(i, 1);
            i--;
        } else {
            break;
        }
    };
    waitObject.set("times", times);
    waitObject.set("timestamp", timestamps);
}

我们需要在循环中为找到的每个 Wait 对象调用它。完成后,我们需要保存所有更改的对象...

Parse.Cloud.job("expireTimes", function(request, response){
    Parse.Cloud.useMasterKey();
    var currentTime = new Date().getTime() / 1000;
    var query = new Parse.Query("Wait");
    query.find().then(function(results) {
        for (var i=0; i<results.length; i++) {
            removeOldWaitTimes(results[i], currentTime);
        }
        return Parse.Object.saveAll(results);
    }).then(function(result) {
        response.success("success");
    }, function(error) {
        response.error(error);
    });
});

请注意,随着等待 class 中的对象数量变大,作业可能会变得太长,或者查询(可以设置为返回 1k 个对象的最大限制)可能会丢失结果.如果这成为一个风险,我们将需要改进查询。 (例如,如果作业每小时运行一次,则没有理由检索一个多小时前更新的 Wait 对象)。

EDIT 说你想像上面那样更新一些,并销毁其他的。为此,您需要处理两个承诺...

Parse.Cloud.job("expireTimes", function(request, response){
    Parse.Cloud.useMasterKey();
    var destroyThese = [];
    var currentTime = new Date().getTime() / 1000;
    var query = new Parse.Query("Wait");
    query.find().then(function(results) {
        var updateThese = [];
        for (var i=0; i<results.length; i++) {
            var result = results[i];
            if (result.get("times").length > 0) {
                removeOldWaitTimes(result, currentTime);
                updateThese.push(result);
            } else {
                destroyThese.push(result);
            }
        }
        return Parse.Object.saveAll(updateThese);
    }).then(function(result) {
        return Parse.Object.destroyAll(destroyThese);
    }).then(function(result) {
        response.success("success");
    }, function(error) {
        response.error(error);
    });
});

我们将 destroyThese 数组放在封闭范围内,以便它可用于承诺链中的下一步。

目前,我没有找到最佳解决方案,但它现在对我有用。

var Progress = Parse.Object.extend(PROGRESS);
var progressQuery = new Parse.Query(Progress);
progressQuery.equalTo("userId", userId)
progressQuery.find({
    success: function (progress){
        for (i = 0; i < progress.length; i++){
            progress[i].set("lastUse", false)
            progress[i].save()
        }

    },
    error: function(object, error) {
        console.log(error)
    }
})