2

I'm having a hard time trying to understand promises, I'm sure I need to use them for this but I don't know how and other answers don't help me at all.

I'd like to loop over an array, query all the results for each value of the array, then after calculating the average value for these results, add the average in an array. After every iterations, this array is sent as a response.

Here is my code which could help understand me here:

Parse.Cloud.define('getScorePeopleArray', function(request, response) {

    var peopleArray = request.params.peoplearray;
    var query = new Parse.Query("Scores");
    var resultat;
    var index, len;
    var resultarray = [];
    var people;

    for (index = 0, len = peopleArray.length; index < len; ++index) {
      people = peopleArray[index];
      query.equalTo("People",people);
      query.find({
        success: function(results) {
          var sum = 0;
          for (var i = 0; i < results.length; ++i) {
           sum += results[i].get("Score");
          }
          resultat = (sum / results.length)*5;
          if(!resultat){
            resultarray.push("null");
          }else{
            resultarray.push(resultat);
          }
        },
        error: function() {
          response.error("score lookup failed");
        }
    }).then();
  }
  response.success(resultarray);  
});

Of course response.success is not called when every queries are done, but as soon as possible (since queries are asynchronous if I'm right). I know I have to change it with promises, but I don't understand at all how this works.

Thanks a lot in advance !

3
  • Do any of these help you? Commented Mar 19, 2015 at 20:01
  • I'll check that, thanks Commented Mar 19, 2015 at 20:25
  • Good suggested reading by @Bergi for promise concurrence generally. You should also check out Parse.Query.or() which also does a union on the results. parse.com/docs/js/api/symbols/Parse.Query.html#.or Commented Mar 19, 2015 at 20:51

1 Answer 1

12
var _ = require('underscore');

Parse.Cloud.define('getScorePeopleArray', function(request, response) {

 var peopleArray = request.params.peoplearray; // what is this an array of?
 var resultArray = [];

  return Parse.Promise.as().then(function() { // this just gets the ball rolling
    var promise = Parse.Promise.as(); // define a promise

    _.each(peopleArray, function(people) { // use underscore, its better :)
      promise = promise.then(function() { // each time this loops the promise gets reassigned to the function below

        var query = new Parse.Query("Scores");
        query.equalTo("People", people); // is this the right query syntax?
        return query.find().then(function(results) { // the code will wait (run async) before looping again knowing that this query (all parse queries) returns a promise. If there wasn't something returning a promise, it wouldn't wait.

          var sum = 0;
          for (var i = 0; i < results.length; i++) {
            sum += results[i].get("Score");
          }
          var resultat = (sum / results.length) * 5;

          if (!resultat){
            resultArray.push("null");
          } else {
            resultArray.push(resultat);
          }

          return Parse.Promise.as(); // the code will wait again for the above to complete because there is another promise returning here (this is just a default promise, but you could also run something like return object.save() which would also return a promise)

        }, function (error) {
          response.error("score lookup failed with error.code: " + error.code + " error.message: " + error.message);
        });
      }); // edit: missing these guys
    });
    return promise; // this will not be triggered until the whole loop above runs and all promises above are resolved

  }).then(function() {
    response.success(resultArray); // edit: changed to a capital A
  }, function (error) {
    response.error("script failed with error.code: " + error.code + " error.message: " + error.message);
  });
});
Sign up to request clarification or add additional context in comments.

6 Comments

That's awesome, thanks ! EDIT: I'll also check other's links to understand better how promises work, it looks really powerful
Forgot to answer your questions on comments: The array is an array of strings, the query syntax looks right (people in the query represents each object of the array right?)
Sorry for the third message in a row, but I have an error: Cannot call method 'then' of undefined. for these lines: "return Parse.Promise.as().then(function() {..." and ".then(function() { response.success(resultarray);..." I'm looking into it
Think I just fixed it. Was missing a closing }); Sorry about that.
Still not working for me : Failed with: ReferenceError: resultarray is not defined at main.js:77:22 at e (Parse.js:2:5101) at Parse.js:2:4651 at Array.forEach (native) at Object.x.each.x.forEach [as _arrayEach] (Parse.js:1:665) at c.extend.resolve (Parse.js:2:4602) at Parse.js:2:5181 at e (Parse.js:2:5101) at Parse.js:2:4651 at Array.forEach (native) I try to do it with just queries and cache policies to make it faster, so don't worry if it stays unsolved Here is the pastebin for you to get the right line numbers: pastebin.com/jKYc2v7c
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.