Imagina que tenemos una función de generador asíncrono:
async f * (connection) { while (true) { ... await doStuff() yield value } }Supongamos que esta función es prácticamente infinita y nos da resultados de algunas acciones asíncronas. Queremos iterar estos resultados:
for await (const result of f(connection)) { ... } Ahora imagine que queremos salir de este ciclo for-await cuando finaliza algún tiempo de espera y limpiar las cosas:
async outerFunc() { setTimeout(() => connection.destroy(), TIMEOUT_MS) for await (const result of f(connection)) { ... if (something) { return 'end naturally' } } } Suponga que connection.destroy() finaliza la ejecución de f y finaliza el ciclo for-await . Ahora sería genial devolver algún valor de la outerFunc cuando finalice el tiempo de espera. El primer pensamiento se envuelve en una Promise :
async outerFunc() { return await new Promise((resolve, reject) => { setTimeout(() => { connection.destroy() resolve('end by timeout') }, TIMEOUT_MS) for await (const result of f(connection)) { // nope ... if (something) { resolve('end naturally') } } }) } Pero no podemos usar awaits dentro de Promise y no podemos async la función debido a este antipatrón.
La pregunta es: ¿cómo regresamos por tiempo de espera de la manera correcta?