2

Is this recursion coded wrong or is it just that console.log() is not always executed even if the recursion is executed?  

function testrecur(s) {
    console.log("begin testrecur=" + s);
    s++;
    if (s < 10) {
        testrecur(s);
    } else {
        return s;
    }
}
Parse.Cloud.define("testrecursion", function(request, response) {
    Parse.Promise.as().then(function() {
        return testrecur(0);
    }).then(function(Result) {
        response.success(Result);
    }, function(error) {
        response.error(error);
    });
});

Executing testrecursion returns no errors in console.

The info console log shows

I2015-10-10T08:55:17.308Z]begin testrecur=0
I2015-10-10T08:55:17.309Z]begin testrecur=1
I2015-10-10T08:55:17.315Z]begin testrecur=7
I2015-10-10T08:55:17.316Z]begin testrecur=8

Executing testrecursion again shows this in the info console log.

I2015-10-10T08:19:15.970Z]begin testrecur=0
I2015-10-10T08:19:15.971Z]begin testrecur=1
I2015-10-10T08:19:15.972Z]begin testrecur=2
I2015-10-10T08:19:15.973Z]begin testrecur=3
I2015-10-10T08:19:15.974Z]begin testrecur=4
I2015-10-10T08:19:15.975Z]begin testrecur=5
I2015-10-10T08:19:15.978Z]begin testrecur=8

Executing testrecursion the 3rd time shows this in the info console log.

I2015-10-10T08:22:14.729Z]begin testrecur=2
I2015-10-10T08:22:14.731Z]begin testrecur=4
I2015-10-10T08:22:14.732Z]begin testrecur=5
I2015-10-10T08:22:14.733Z]begin testrecur=6
I2015-10-10T08:22:14.734Z]begin testrecur=7

After testing this dozens of times, the recursive steps appear to be called sporadically. The output seems to be random. The expected output is

I2015-10-10T08:19:15.970Z]begin testrecur=0
I2015-10-10T08:19:15.971Z]begin testrecur=1
I2015-10-10T08:19:15.972Z]begin testrecur=2
I2015-10-10T08:19:15.973Z]begin testrecur=3
I2015-10-10T08:19:15.974Z]begin testrecur=4
I2015-10-10T08:19:15.975Z]begin testrecur=5
I2015-10-10T08:19:15.975Z]begin testrecur=6
I2015-10-10T08:19:15.975Z]begin testrecur=7
I2015-10-10T08:19:15.975Z]begin testrecur=8
I2015-10-10T08:19:15.975Z]begin testrecur=9

Does this look like the recursion is happening correctly, and it's just that the console log is not logging all the messages?

I'm trying to implement what Hector Ramos mentioned in https://www.parse.com/questions/error-too-many-recursive-calls-into-cloud-code You can use recursion, you just can't recursively call Cloud Functions since that Cloud Function request will execute on a different thread. Use regular JavaScript functions, initiated from a Cloud Function, instead. - Héctor Ramos about 2 years ago

Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
Henry Situ
  • 153
  • 14
  • 1
    What happens in the console if you just run `testrecur(0);` – Jaromanda X Oct 12 '15 at 07:49
  • Thanks Jaromanda X, what's the best way to run testrecur(0); in the console? In Chrome? Currently, I'm running the cloud function "testrecursion" from the command line using curl -X POST -H "X-Parse-Application-Id: 9asjfpoiajwp982hi9ou23jk -H "X-Parse-REST-API-Key: ua9difaspasi9as8df2j -H "Content-Type: application/json" -d '{ }' https://api.parse.com/1/functions/testrecursion – Henry Situ Oct 12 '15 at 07:58
  • 1
    you type `testrecur(0);` in the console – Jaromanda X Oct 12 '15 at 07:59
  • 1
    oh, sorry, you copy the `testrecur` function into the console. hit enter, then type the above – Jaromanda X Oct 12 '15 at 08:06
  • Thanks Jaromanda X, I created a test web page with Then in Chrome console, manually executing testrecur(0); works perfectly. As expected, 10 console log output lines show up, 1 for each recursive step. – Henry Situ Oct 12 '15 at 08:16
  • 1
    does the console suffer the same gaps when you execute `testrecur(0)` ? – Jaromanda X Oct 12 '15 at 08:17
  • Console works as expected. Do you think the logging function (i.e. console.log("...")) in parse.com is just not guaranteed to run? e.g. maybe the recursion code is also working in cloud code, but it's just that each recursive step is not logged because the server may have been busy so the server may electively discard low priority function calls such as logging. What's a good way to confirm if the recursion is actually working in cloud code? I tried "return testrecur(0);" but the "Result" variable is undefined. If the returned value is 10, then we know recursion is working in cloud code. – Henry Situ Oct 12 '15 at 08:22
  • 1
    it's undefined because you need to `return testrecur(s);` in testrecurs. I've seen console.log's be sporadic in chrome before. Not sure if it's a chrome thing or if there are other factors – Jaromanda X Oct 12 '15 at 08:28

1 Answers1

0

It turns out that testrecur() needs to return a promise so that the caller, in this case, testrecursion() will wait for testrecur() to complete before starting the next chain in the promise. The actual code is available at How to return a value from a regular javascript function that contains a promise chain?

By the way, the recursion code in this question is correct because the recursion is happening correctly. We just need to tie the promises in sequence so each recursive call can have the opportunity to execute completely before the calling function completes.

Community
  • 1
  • 1
Henry Situ
  • 153
  • 14