简体   繁体   English

解析云代码链承诺

[英]Parse Cloud Code Chain Promises

I am trying to clean my Parse Cloud Code functions to make them easier to maintain. 我正在尝试清理我的Parse Cloud Code函数,以使其更易于维护。 To do so I tried to use Promises but I can't get rid of errors. 为此,我尝试使用Promises,但是我无法摆脱错误。

Here is the aim of my code : 这是我的代码的目的:

  • Decrement score of User1 User1的减分
  • Push a notification to User2 saying --> User1.name is asking you to : Action User2推送通知,说-> User1.name要求您执行以下操作

Actual Cloud Code (working) : 实际的云代码(有效):

Parse.Cloud.useMasterKey();
var action = request.object.get("action");
var from = request.object.get("from");
var to = request.object.get("to");
var reward = request.object.get("reward");

// Query 'from User' to decrement his score
var queryScore = new Parse.Query(Parse.User);
queryScore.get(from.id, {
  success: function(score)
  {
    // Decrement score of 'fromUser'.
    var newScore = score.get("score");
    newScore -= reward;
    score.set("score", newScore);

    score.save(null, {
      success: function(success)
      {
        // Score was saved.
        // Find devices associated with 'to User'
        var queryTo = new Parse.Query(Parse.User);
        queryTo.equalTo("objectId", to.id);
        var pushQueryTo = new Parse.Query(Parse.Installation);
        pushQueryTo.matchesQuery("user", queryTo);

        pushQueryTo.first({
          success: function(installation)
          {
            // Device found
            // Fetch 'from User' infos
            from.fetch({
              success: function(User) {

                // 'from User' fetched
                // Send Push to 'to User'
                var first_name = User.get("first_name");

                var preferredLanguages = installation.get("preferredLanguages");
                var alert = ""

                switch (preferredLanguages) {
                  case "fr":
                    alert = first_name + " vous demande de : " + action
                    break;
                  default:
                    alert = first_name + " is asking you to : " + action
                }

                Parse.Push.send({
                    where: pushQueryTo,
                    data: {
                      "alert": alert,
                      "badge": "Increment",
                      "content-available": "1",
                      "type": "actionAsked",
                      "sound": "default"
                    }
                  });

                  // Everything is done!
                  response.success();

              },
              error: function(error) {
                // An error occurred.
                response.error(error);
              }
            });
          },
          error: function(error)
          {
            // An error occurred.
            response.error(error);
          }
        });
      },
      error: function(error)
      {
        // An error occurred.
        response.error(error);
      }
    });

  },
  error: function(error)
  {
    // An error occurred.
    response.error(error);
  }
});

Chain Promises Cloud Code (not working) : 链承诺云代码(不起作用):

Parse.Cloud.useMasterKey();
var action = request.object.get("action");
var from = request.object.get("from");
var to = request.object.get("to");
var reward = request.object.get("reward");

// Query 'from User' to decrement his score
var queryScore = new Parse.Query(Parse.User);
queryScore.get(from.id).then(function(score) {

    // Decrement score of 'fromUser'.
    var newScore = score.get("score");
    newScore -= reward;
    score.set("score", newScore);

    return score.save();

}).then(function(result) {

    // Score was saved.
    // Find devices associated with 'to User'
    var queryTo = new Parse.Query(Parse.User);
    queryTo.equalTo("objectId", to.id);
    var pushQueryTo = new Parse.Query(Parse.Installation);
    pushQueryTo.matchesQuery("user", queryTo);

    return pushQueryTo.first();

}).then(function(device) {

    // Device found
    // Fetch 'from User' infos

    return from.fetch();

}).then(function(from){

    // 'from User' fetched
    // Send Push to 'to User'
    var first_name = from.get("first_name");
    var preferredLanguages = device.get("preferredLanguages");
    var alert = ""

    switch (preferredLanguages) {
        case "fr":
            alert = first_name + " vous demande de : " + action
            break;
        default:
            alert = first_name + " is asking you to : " + action
    }

    Parse.Push.send({
        where: pushQueryTo,
        data: {
            "alert": alert,
            "badge": "Increment",
            "content-available": "1",
            "type": "actionAsked",
            "sound": "default"
        }
    });

    // Everything is done!
    response.success();

},function(error) {

    // An error occurred.
    response.error(error);

});

The error I get : 我得到的错误:

Apparently my error is concerning the "device" variable. 显然我的错误与“设备”变量有关。

In converting to promises you have also un-nested, causing device and pushQueryTo no longer to be in scope in later handlers. 在转换为pushQueryTo ,您也没有嵌套,导致devicepushQueryTo不再在以后的处理程序中。 With nicely indented code (as in the question), scope issues like this are readily observable in the source. 使用缩进的代码(如问题所示),在源代码中很容易观察到这样的范围问题。

Fortunately, wherever a then() handler returns a promise, you are afforded some freedom to chain directly to the expression that returns that promise, instead of adding to the outermost promise chain. 幸运的是,无论then()处理程序返回promise的位置如何,您都可以自由地直接链接到返回该promise的表达式,而不必添加到最外层的promise链中。

A fix here is simply to re-introduce some of the nesting by chaining directly to pushQueryTo.first() and from.fetch() . 此处的解决方法是通过直接链接到pushQueryTo.first()from.fetch()来重新引入一些嵌套。

Parse.Cloud.useMasterKey();
var action = request.object.get("action");
var from = request.object.get("from");
var to = request.object.get("to");
var reward = request.object.get("reward");

var queryScore = new Parse.Query(Parse.User);
queryScore.get(from.id)
.then(function(score) {
    score.set('score', score.get('score') - reward);
    return score.save();
})
.then(function(result) {
    var queryTo = new Parse.Query(Parse.User);
    queryTo.equalTo('objectId', to.id);
    var pushQueryTo = new Parse.Query(Parse.Installation);
    pushQueryTo.matchesQuery('user', queryTo);
    return pushQueryTo.first()
    .then(function(device) {
        return from.fetch()
        .then(function(from) {
            var alert;
            switch (device.get('preferredLanguages')) {
                case 'fr': alert = from.get('first_name') + ' vous demande de : ' + action; break;
                default: alert = from.get('first_name') + ' is asking you to : ' + action;
            }
            Parse.Push.send({
                where: pushQueryTo,
                data: { 'alert': alert, 'badge': 'Increment', 'content-available': '1', 'type': 'actionAsked', 'sound': 'default' }
            });
            response.success();
        });
    });
}).catch(function(error) {
    response.error(error);
});

Please note that I said this is "a" solution, not "the" solution. 请注意,我说的是“一个”解决方案,而不是“该”解决方案。 In other words, other approaches exist. 换句话说,存在其他方法。 The whole topic of accessing previous promise results in a .then() chain is discussed very comprehensively here . 非常全面地讨论了访问先前的诺言结果导致.then()链的整个主题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM