解析云代码链承诺

时间:2015-07-31 13:15:24

标签: javascript parse-platform promise cloud-code

我正在尝试清理我的Parse Cloud Code函数,以使它们更易于维护。 为此,我尝试使用Promises,但我无法摆脱错误。

以下是我的代码的目标:

  • User1
  • 的评分
  • 将通知推送到 User2 说 - > User1.name 要求您:操作

实际云代码(正常工作):

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(不工作):

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

});

我得到的错误:

显然我的错误是关于"设备"变量

1 个答案:

答案 0 :(得分:4)

转换为promises时,您也已取消嵌套,导致devicepushQueryTo不再在后续处理程序中。使用简洁的缩进代码(如问题中所示),这样的范围问题在源代码中很容易被观察到。

幸运的是,只要then()处理程序返回一个promise,就可以直接链接到返回该promise的表达式,而不是添加到最外层的promise链。

此处的修复只是通过直接链接到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);
});

请注意我说这是" a"解决方案,而不是""解。换句话说,存在其他方法。 here 非常全面地讨论了.then()链中访问先前承诺结果的整个主题。