Анализировать фоновое задание Parse Server Cloud Code и обновлять объекты - PullRequest
0 голосов
/ 12 октября 2018

У меня есть приложение Parse Server, размещенное на back4app, и я запускаю фоновое задание, которое запускается каждую минуту и запрашивает класс Letters, где столбец 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, где deliveryDate установлено вчера, для менячтобы проверить эту функцию облачного кода.Есть еще один столбец с именем 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, которыйотправляет push-уведомления и нуждается в некоторых параметрах.Обычно я вызываю его из своего приложения, как бы я вызвал его из этой функции?

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

1 Ответ

0 голосов
/ 13 октября 2018

Любое save(), которое выполняется или еще не началось при вызове response.success(), будет прервано (или не получит шанса на запуск).Чтобы исправить, соберите обещания для всех сохранений и запустите их вместе с 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)
});
...