简体   繁体   中英

wait for query to finish before sending response

i'm using Cloud Code to execute something on the server side. In my code i had to do a series of queries which should do in a while loop. Those queries should be done after each other. When i run the code, it goes into each query and returns before finishing the queries, hence getting a socket timeout connection error. Is there a way to wait for a query to finish before proceeding? any example will be highly appreciated. Thank you.

Edit: here is a code snippet

while (i < cities.length-1){
            if (query) {
                query = false;
                cities.forEach(function(object){
                    var query = new Parse.Query("pictures");
                    query.descending("likes");
                    query.equalTo("city", object);
                    query.limit(1);
                    query.find().then(function(results){
                        success: function(results) {
                            var tempArray = new Array();
                            tempArray = results;

                            rankedPosts = rankedPosts.concat(tempArray);

                            query = true;
                            i++;
                        }, error: function() {
                            response.error("Error");
                        }
                    });
                });
            };
        }

I think you need to make a Promise series

See https://parse.com/docs/js_guide#promises-series

Make something like this:

  // Create a trivial resolved promise as a base case.
  var promise = Parse.Promise.as();

  var finalResults = [];

  // for all the objects in the array...
  _.each(cities, function(objectX) { // the "_" is given by using "var _ = require('underscore');" at the beginning of your module

       // For each item, extend the promise with a function to query specified objectX
       promise = promise.then(function() {

           var subPromise = new Parse.Promise();

           var query = new Parse.Query("pictures");
           query.descending("likes");
           query.equalTo("city", objectX);
           query.limit(1);

           query.find().then(function(results) {

               // append cur results to final results
               finalResults = _.union (finalResults,results);
               subPromise.resolve(results);

           }, function(error) {

               subPromise.reject(error);

           });

           return subPromise;
       });

  });
  return promise;

}).then(function() {

  // When all queries have been performed

});

I've not tested this code, but i've already used something like this with success.

Anyway, keep in mind the restriction of Parse.com about the request duration. So, 3 seconds in the events listener (like beforeSave or afterSave), 7 seconds in the custom functions and 15 minutes maximum in the background jobs.

Hope it helps

Looks like you could actually do this work in parallel queries (instead of series). I solved a similar problem where I had to return an array of boolean results. Had to return true/false if a ParseUser existed with one of the phone numbers in the request array.

Inspired by: https://parse.com/docs/js_guide#promises-parallel

Parse.Cloud.define("phone_search", function(request, response) {

  var list = request.params.phones;

  //Initialize result array
  var finalResults = [];
  for (var i = 0; i < list.length; i++){
    finalResults[i] = false;
  }

  Parse.Promise.as().then(function() {
    // Collect one promise for each query into an array.
    var promises = [];

    for (var i = 0; i < list.length; i++){
      (function (j) {  //create new closure so i changes with each callback
          var number = list[j];
          var query = new Parse.Query('_User');
          query.equalTo("phoneNumber", number);

          promises.push(
            query.find({
              success: function(results) {
                if (results.length > 0) {
                  console.log("Found one:"+number); 
                  finalResults[j] = true;
                }
              },
              error: function() {
                response.error();
              }
            })        
          );
      })(i);
    }
    // Return a new promise that is resolved when all of the queries are finished.
    return Parse.Promise.when(promises);

  }).then(function() {
    console.log(finalResults); 
    response.success(finalResults);
  });


});

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