简体   繁体   中英

Parse Javascript Cloud Code .save() works only on a single user

I use Parse in iOS to run a cloud code method that gets an ID in it's request and receives a number in the response.

The purpose of the cloud code function is to take the request ID and add it to a field of 3 different users.

Here is the cloud code method in Javascript:

amount = 3;
// Use Parse.Cloud.define to define as many cloud functions as you want.
// For example:
Parse.Cloud.define("addToIDs", function(request, response) {

   var value = request.params.itemId;

   var query = new Parse.Query(Parse.User);
   query.ascending("createdAt");
   query.limit(100);
   query.find({
     success: function(results) {
      var sent = 0;
      for (var i = 0; i < results.length; i++) {
        var idlst = results[i].get("idString"); 
        if (idlst != null && idlst.indexOf(value) <= -1) {
          idlst += value+"|";
          results[i].set("idString", idlst);
          results[i].save();
          sent = sent+1;
        }
        if (sent >= amount) {
          break;
        }
      }
      response.success(sent);
    },
    error: function() {
      response.error("Test failed");
    }
  });
});

When running this cloud code method I get a response of '3' meaning it called .save for 3 users. The problem is that when i go back to look in the Database viewer in the parse website it actually only updated a single user (Its always the same user). No matter how many times i run this code, it will only actually update the first user..

Anyone know why this is happening?

Both save and saveAll are asynchronous, so you should make sure the saving process is done. Also note that, the user object can only be updated by the owner or request with masterkey .

The following code should work:

var amount = 3;
Parse.Cloud.define("addToIDs", function(request, response) {

    var value = request.params.itemId;

    var query = new Parse.Query(Parse.User);
    query.ascending("createdAt");
    query.limit(100);
    return query.find()
        .then(function(results) { // success
            var toSave = [];
            var promise = new Parse.Promise();
            for (var i = 0; i < results.length; i++) {
                var idlst = results[i].get("idString");
                if (idlst != null && idlst.indexOf(value) <= -1) {
                    idlst += value+"|";
                    results[i].set("idString", idlst);
                    toSave.push(results[i]);
                }
                if (toSave.length >= amount) {
                    break;
                }
            }
            // use saveAll to save multiple object without bursting multiple request
            Parse.Object.saveAll(toSave, {
                useMasterKey: true,
                success: function(list) {
                    promise.resolve(list.length);
                },
                error: function() {
                    promise.reject();
                }
            });
            return promise;    
        }).then(function(length) { // success
            response.success(length);
        }, function() { // error
            response.error("Test failed");
        });
});

The reason this is happening is two-fold:

  1. save() is an asynchronous method, and
  2. response.success() will immediately kill your running code as soon as it's called.

So what's happening is that inside your for loop you're running save() several times, but since it's asynchronous, they're simply thrown into the processing queue and your for loop continues on through. So it's quickly throwing all of your save() 's into the processing queue, and then it reaches your response.success() call but, by the time it's reached, only one of the save() 's has had a chance to successfully process.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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