Parse Server Cloud Code 后台作业查询和更新对象

Parse Server Cloud Code background job query and update objects

我在 back4app 上托管了一个 Parse Server 应用程序,我是 运行 一个后台作业 每分钟运行一次 并查询 Letters class,其中 deliveryDate 列小于或等于当前日期,这是我的 main.js 文件:

// DELIVER A LETTER
Parse.Cloud.job("deliverLetter", function (request, status) {
    var now = new Date();
    // var nowTime = date.getTime();

    var Letters = Parse.Object.extend("Letters");
    var query = new Parse.Query(Letters);
    query.lessThanOrEqualTo("deliveryDate", now);
    query.find().then (function (objects) {
        objects.forEach(function (obj) {
            obj.set("isDelivered", true);

            Parse.Cloud.useMasterKey();
            obj.save(null, { useMasterKey: true } ).then(function(obj) {
                response.success(obj);
            }, function(error) {
                response.error(error)
            });
    });
});

因此,例如,我在 Letters class 中保存了一行,其中 deliveryDate 设置为昨天,以便我测试此 Cloud Code 功能。还有一个名为 isDelivered 的列,它被设置为 False。因此,我上面的函数应该将 isDelivered 设置为 True 并更新我的 Letters 对象。

但是它不起作用,所以我不知道我做错了什么。

编辑

感谢 danh,我已按如下方式修复我的代码:

var Letters = Parse.Object.extend("Letters");
    var query = new Parse.Query(Letters);
    query.lessThanOrEqualTo("deliveryDate", now);
    query.equalTo("isDelivered", false);

    query.find().then (function (objects) {
        let savePromises = objects.map(function (obj) {
            obj.set("isDelivered", true);
            return obj.save(null, { useMasterKey: true } );
        });
        Promise.all(savePromises).then(function(obj) {
            response.success(obj);
        }, function(error) {
            response.error(error)
        });
    });

我需要从我的 main.js 文件中调用另一个函数,该函数发送推送通知并需要一些参数。我通常从我的应用程序中调用它,如何从上述函数中调用它?

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

  var user = request.user;
  var params = request.params;
  var userObjectID = params.userObjectID
  var data = params.data

  var recipientUser = new Parse.User();
  recipientUser.id = userObjectID;

  var pushQuery = new Parse.Query(Parse.Installation);
  pushQuery.equalTo("userID", userObjectID);

  Parse.Push.send({
    where: pushQuery,
    data: data
  }, { success: function() {
      console.log("#### PUSH SENT!");
  }, error: function(error) {
      console.log("#### PUSH ERROR: " + error.message);
  }, useMasterKey: true});
  response.success('success');
});

也许进入 Promise.all()?

Promise.all(savePromises).then(function(obj) {
     response.success(obj);

Parse.Cloud.define("pushiOS"...

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

调用 response.success() 时任何正在进行或尚未开始的 save() 将被终止(或没有机会开始)。要修复,收集所有保存的承诺,并将它们 运行 与 Promise.all() 一起解决,只有在传递给它的所有承诺都已解决后才会解决。

query.find().then (function (objects) {
    // Parse.Cloud.useMasterKey(); don't need this
    let savePromises = objects.map(function (obj) {
        obj.set("isDelivered", true);
        return obj.save(null, { useMasterKey: true } );
    });
    Promise.all(savePromises).then(function(obj) {
        response.success(obj);
    }, function(error) {
        response.error(error)
    });
});

另外,请注意,顺便说一句,query.lessThanOrEqualTo("deliveryDate", now); 将获取之前具有 deliveryDates 的所有对象,包括您之前处理的对象。随着时间的推移,该结果将单调地变长,最终超过 运行 秒之间的 1 分钟,或者耗尽其他一些系统资源。

也许你真的想要...

query.lessThanOrEqualTo("deliveryDate", now);
query.equalTo("isDelivered", false);

编辑

第二个问题可以通过像这样分解一个承诺返回的推送函数来处理...

function pushDataToUser(userID, data)
    var recipientUser = new Parse.User();
    recipientUser.id = userID;
    let pushQuery = new Parse.Query(Parse.Installation);
    pushQuery.equalTo("userID", userID);
    return Parse.Push.send({ where:pushQuery, data:data });
}

可以像这样从云代码中调用...

Parse.Cloud.define("pushiOS", function(request, response) {
    let params = request.params;
    pushDataToUser(params.userObjectID, params.data).then(function() {
        console.log("#### PUSH SENT!");
        response.success('success');
    }, function(error) {
        console.log("#### PUSH ERROR! " + JSON.stringify(error));
        response.error(error);
    });
}

...并且可以像这样将新的承诺返回函数添加到任何其他承诺链...

// function doSomething() returns a promise (like from a find() or a save()
return doSomething().then(function() {
    // initialize someId and someData
    return pushDataToUser(someId, someData)
});