Search code examples
javascriptrecursionparse-platformparse-cloud-code

From a cloud function: how to call JavaScript function that is recursive?


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


Solution

  • 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.