Soy bastante principiante con javascript y node.js, así que discúlpeme si la pregunta puede considerarse demasiado simple.
Me preguntaba, si tengo una función que devuelve una Promesa, y en su resolución () vuelve a llamar a la misma función en una especie de recursión, ¿puede esto causar un desbordamiento de pila en caso de que no se resuelva?
Puedes imaginarlo de la siguiente manera:
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 } }) }Estaba preguntando esto porque noté que se ejecuta la instrucción de retorno, y esto debería (en mi opinión) desasignar la pila de contexto de la función y evitar problemas como desbordamientos de pila. ¿Me estoy perdiendo algo y luego arriesgo problemas o tengo razón y esto puede considerarse bastante seguro como práctica?
myFunction es una función async , por lo que puede tratarla como una función que siempre devuelve una Promesa y puede llamarla de forma recursiva.
Es seguro resolve una Promesa en un constructor de Promesa:
El parámetro de
valueresolutionFuncpuede ser otro objeto de promesa, en cuyo caso la promesa se inserta dinámicamente en la cadena de promesa.
Y también es seguro devolver una Promesa desde una función async :
El valor de retorno de una función asíncrona está envuelto implícitamente en
Promise.resolve, si aún no es una promesa (como en los ejemplos).
... donde Promise.resolve se describe como retornando:
Una
Promiseque se resuelve con el valor dado, o la promesa pasada como valor, si el valor era un objeto de promesa.
Sin embargo: no debería haber ninguna razón para devolver una new Promise en su uso de async aquí: la función async ya envuelve todo lo que puede devolver en una Promesa, por lo que puede omitir el antipatrón de construcción de Promesa explícito . (Reserve su uso del constructor Promise solo cuando esté adaptando una llamada de estilo de devolución de llamada en promesas, lo que puede ocurrir en funciones async y no async ).
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)); } } Aún deberá verificar que este caso recursivo sea seguro en función de someCondition y de las modificaciones recursivas que realice en myInputValue : si no se salva de su caso recursivo, es posible que se encuentre con un desbordamiento de pila, o puede quedarse sin de memoria montón o girar para siempre. (En las funciones async , la función se ejecuta de forma síncrona hasta el primer await , pero los controladores de Promise siempre se llaman con una pila vacía según Promises/A+ 2.2.4 y ES6 ).