【问题标题】:Parse Server Cloud Code background job query and update objectsParse Server Cloud Code 后台作业查询和更新对象
【发布时间】:2018-10-12 06:22:13
【问题描述】:

我有一个托管在 back4app 上的 Parse Server 应用程序,我正在运行一个每分钟运行一次的后台作业,并查询 Letters 类,其中 deliveryDate 列小于或等于当前日期,这是我的 ma​​in.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 类中保存了一行 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)
});

【问题讨论】:

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


    【解决方案1】:

    当调用response.success() 时,任何正在进行或尚未启动的save() 将被终止(或没有机会启动)。要解决此问题,请收集所有保存的 Promise,并将它们与 Promise.all() 一起运行,这只有在传递给它的所有 Promise 都已解决后才会解决。

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

    ...并且新的 promise-returning 函数可以像这样添加到任何其他 promise 链中...

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

    【讨论】:

    • 非常感谢您的回答,什么是“承诺”?也许你的意思是“字母”??
    • :-) Promise 是您发送then 的对象。 Query.find 和 Object.save 都返回承诺。 Promise.all() 运行一组。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    • 我明白了,我不知道,谢谢,我现在就试试你的代码;)
    • 当然。这是一个特定于解析的文档...docs.parseplatform.org/js/guide/#promises 这是我最喜欢的 JS 部分,它承诺让异步编程变得如此简单。还有一种更现代的语法叫做 async-await,你也应该去看看。
    • 再次感谢,它就像一个魅力,我已经编辑了我的问题,希望你也可以帮助我解决一个新问题;)无论如何,我已经接受了你的回答。跨度>
    猜你喜欢
    • 1970-01-01
    • 2016-11-12
    • 2016-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多