I am quite a beginner with javascript and node.js, so forgive me if the question can be considered as too simple.
I was wondering, if I have a function that returns a Promise, and in its resolve() it calls again the same function in a sort of recursion, can this cause a stack overflow in case it does not get resolved?
You can imagine it as it follows:
var someVariable = await myFunction(someInput)
async function myFunction(myInputValue) {
return new Promise(function(resolve, reject) {
// do some computation
if (someCondition) {
resolve(true)
return
} else {
resolve(myFunction(myInputValue))
return
}
})
}
I was asking this since I noticed the return instruction gets executed, and this should (in my opinion) deallocate the function's context stack and avoid getting issues like stack overflows. Am I missing something and then I am risking issues or am I right and this can be considered quite safe as practice?
myFunction is an async function, so you can treat it as a function that always returns a Promise, and you can call it recursively.
It is safe to resolve to a Promise in a Promise constructor:
The
resolutionFuncvalueparameter can be another promise object, in which case the promise gets dynamically inserted into the promise chain.
And it is also safe to return a Promise from an async function:
The return value of an async function is implicitly wrapped in
Promise.resolve- if it's not already a promise itself (as in the examples).
...where Promise.resolve is described as returning:
A
Promisethat is resolved with the given value, or the promise passed as value, if the value was a promise object.
However: There should be no reason to return a new Promise in your use of async here: The async function already wraps anything it can return in a Promise, so you can skip the explicit Promise construction antipattern. (Reserve your use of the Promise constructor only when you are adapting a callback-style call into promises, which can happen in async and non-async functions.)
var someVariable = await myFunction(someInput)
async function myFunction(myInputValue) {
// do some computation on myInputValue that awaits something
if (someCondition) {
return true;
} else {
return myFunction(someModificationOf(myInputValue));
}
}
You'll still need to check that this recursive case is safe based on someCondition and whatever recursive modifications you do to myInputValue: If you don't bail out of your recursive case, then you might encounter a stack overflow, or you might run out of heap memory or spin forever. (In async functions, the function runs synchronously up until the first await, but Promise handlers are always called with an otherwise-empty stack per Promises/A+ 2.2.4 and ES6.)