【问题标题】:Parse: Update Object from Cloud Code解析:从云代码更新对象
【发布时间】:2017-12-07 18:12:48
【问题描述】:

我创建了一个后台作业,每分钟运行一次。它的目的是删除数据库中旧的或过时的数据。在这种情况下,用户提交一个附有时间戳的时间,这两个值存储在数组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 数组中。好吧,如果我每分钟都有后台工作,那么一些条目不会超过一个小时。我想保留那些,但摆脱其他的。

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

【问题讨论】:

    标签: javascript parse-platform parse-cloud-code


    【解决方案1】:

    答案的基本部分是可以使用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);
    }
    

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

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

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

    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 数组放在封闭范围内,以便它可用于 Promise 链中的下一步。

    【讨论】:

    • 非常感谢您为我做这件事。我真的很感激。如果数组为空,我们是否可以检查删除函数以删除整个对象?或者我应该创建另一个后台函数来检查times 数组是否为空,如果是,则删除整个对象?
    • 您也可以使用destroyAll() 一次删除一个批次,但这将是两个异步操作,我们需要更复杂的操作才能正确执行此操作。我会尝试在编辑中回答...
    • 好的,非常感谢!这对我帮助很大!
    • 快速查看docs 表示Parse.Object.saveAll 不会返回承诺...(它们可能已过时)快速修复:gist.github.com/hhanesand/b809d6f1d438174e2d91
    • @lightice11 - saveAll() 返回一个承诺。文档中的遗漏错误。要点看起来正确但没有必要。
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多