解析 afterSave 函数被跳过

Posted

技术标签:

【中文标题】解析 afterSave 函数被跳过【英文标题】:Parse afterSave function getting skipped over 【发布时间】:2014-10-15 16:56:53 【问题描述】:

所以我有一个使用 parse.com 作为后端的消息传递应用程序。当我从应用程序发送消息时,它会将其保存在 Parse.com 上的一个名为“NewMessages”的类中。然后在我的云代码中,我有一个专门用于此类的 afterSave 函数,这样当一个新对象保存到“NewMessages”时,它会随机选择一个用户将其附加到消息中并将其保存在一个名为“Inbox”的新类中。然后它从“NewMessages”中删除原始消息。

所以“NewMessages”类应该总是为空的吧?但是当我很快发送一堆消息时,有些消息会被跳过。我该如何解决这个问题?

有没有比使用 afterSave 更好的方式来构建它?

function varReset(leanBody, leanSenderName, leanSenderId, randUsers)
   leanBody = "";
   leanSenderName = "";
   leanSenderId = "";
   randUsers = [];
   console.log("The variables were set");



Parse.Cloud.afterSave("Lean", function(leanBody, leanSenderName, leanSenderId, randUsers, request) 
  varReset(leanBody, leanSenderName, leanSenderId, randUsers);

  var query = new Parse.Query("NewMessages");
  query.first(
    success: function(results)
      leanBody = (results.get("MessageBody"));
      leanSenderName = (results.get("senderName"));
      leanSenderId = (results.get("senderId"));
      getUsers(leanBody, leanSenderName, leanSenderId);
      results.destroy(
        success: function(results)
          console.log("deleted");
        , error: function(results, error)
        
      );
    , error: function(error)
    

  );
);

  function getUsers(leanBody, leanSenderName, leanSenderId, response)

    var query = new Parse.Query(Parse.User);
    query.find(
        success: function(results)
            var users = [];
            console.log(leanBody);
            console.log(leanSenderName);

            //extract out user names from results
            for(var i = 0; i < results.length; ++i)
                users.push(results[i].id);
            
            for(var i = 0; i < 3; ++i)
                var rand = users[Math.floor(Math.random() * users.length)];
                var index = users.indexOf(rand);
                users.splice(index, 1);
                randUsers.push(rand);
                
            console.log("The random users are " + randUsers);
            sendMessage(leanBody, leanSenderName, leanSenderId, randUsers);
        , error: function(error)
            response.error("Error");
        
    );
  

  function sendMessage(leanBody, leanSenderName, leanSenderId, randUsers)
    var Inbox = Parse.Object.extend("Inbox");

    for(var i = 0; i < 3; ++i)

      var inbox = new Inbox();
      inbox.set("messageBody", leanBody);
      inbox.set("senderName",  leanSenderName);
      inbox.set("senderId", leanSenderId);
      inbox.set("recipientId", randUsers[i]);
      console.log("leanBody = " + leanBody);
      console.log("leanSenderName = " + leanSenderName);
      console.log("leanSenderId = " + leanSenderId);
      console.log("recipient = " + randUsers[i]);

      inbox.save(null, 
        success: function(inbox) 
          // Execute any logic that should take place after the object is saved.
          alert('New object created with objectId: ' + inbox.id);
        ,
        error: function(inbox, error) 
          // Execute any logic that should take place if the save fails.
          // error is a Parse.Error with an error code and message.
          alert('Failed to create new object, with error code: ' + error.message);
        
      );
    
  

【问题讨论】:

能贴出相关代码吗? afterSave 不应该是这样的:Parse.Cloud.afterSave("Comment", function(request) ... ?你怎么有5个回调参数? 【参考方案1】:

    您检查过您的日志吗?您可能会违反资源限制 (https://parse.com/docs/cloud_code_guide#functions-resource)。如果即时性不重要,那么可能值得考虑设置一个每隔几分钟运行一次并处理未传递消息的后台作业。也可以将这两种方法结合起来:让 afterSave 函数尝试立即发送到收件箱,而后台作业会定期接收任何剩余的 NewMessage。不是最漂亮的解决方案,但至少你有更多的可靠性。 (您必须考虑竞争条件,尽管两者可能会尝试在同一个 NewMessage 上进行传递。)

    关于您关于更好结构的问题,如果两个类相同(或足够接近),是否可以只使用 Messages 类?最初,“to”字段将为空,但在 beforeSave 函数中分配了一个随机收件人。这可能会更快更整洁。

编辑:添加最初是评论的第三个观察:

我看到您在 afterSave 中使用 Query.first() 来查找要处理的 NewMessage。在调用 afterSave 和运行 Query 之间,可能会有一个新的 NewMessage 潜入。为什么不获取保存的 NewMessage 的 ID 并在 Query 中使用它,而不是 first()

query.get(request.object.id,...);

这确保 afterSave 中的代码处理调用它的 NewMessage,而不是最近保存的那个。

【讨论】:

第二个选项听起来确实好多了,但是我想将它发送给三个随机用户(为了简单起见,我把它省略了)所以如果我对此使用 beforeSave 函数我会需要将原始邮件分配给一个随机收件人,然后再为其他两个收件人复制两份邮件副本?谢谢 Parse 允许在列中使用数组,因此您可以在“收件人”列中的数组中存储 3 个收件人(即用户类的对象)。 我刚刚又读了一遍你的代码。我看到您在 afterSave 中使用 Query.first() 来查找要处理的 NewMessage。在调用 afterSave 和运行 Query 之间,可能会有一个新的 NewMessage 潜入。为什么不获取保存的 NewMessage 的 ID 并在 Query 中使用它,而不是 first()? (query.get(request.object.get("NewMessage").id,...);) 这可确保 afterSave 中的代码处理调用它的 NewMessage,而不是最近保存的。 太棒了!我要试试这个

以上是关于解析 afterSave 函数被跳过的主要内容,如果未能解决你的问题,请参考以下文章

为什么连续的scanf会被跳过或不执行

为什么连续的scanf会被跳过或不执行

第二个 cin 被跳过或无法正常工作

Antlr Eclipse IDE White Space 未被跳过

setInterval 在第一次调用时被跳过,并且 Clearinterval 在调用 Javascript 时没有停止

aftersave 生命周期函数