MDN dice que for await...of tiene dos casos de uso:
La
for await...ofinstrucción crea un ciclo que itera sobre objetos iterables asíncronos, así como en iterables sincronizados, ...
Anteriormente estaba al tanto de lo anterior: los iterables asíncronos usando Symbol.asyncIterator. Pero ahora estoy interesado en lo último: iterables sincrónicos.
El siguiente código itera sobre un iterable síncrono: una serie de promesas. Parece bloquear el progreso en el cumplimiento de cada promesa.
async function asyncFunction() {
try {
const happy = new Promise((resolve)=>setTimeout(()=>resolve('happy'), 1000))
const sad = new Promise((_,reject)=>setTimeout(()=>reject('sad')))
const promises = [happy, sad]
for await(const item of promises) {
console.log(item)
}
} catch (err) {
console.log(`an error occurred:`, err)
}
}
asyncFunction() // "happy, an error occurred: sad" (printed in quick succession, after about 5 seconds)
El comportamiento parece ser similar a esperar cada promesa por turno, según la lógica que se muestra a continuación. ¿Es correcta esta afirmación?
Pregunto porque este patrón de código tiene un error implícito de rechazo de conexión Promise.ally Promise.allSettledevitarlo, y me parece extraño que este patrón sea respaldado explícitamente por el lenguaje.
fuente

for await... ofcorrecta mi descripción de iterables sincrónicos? De ser así, ¿importa que ese patrón pueda emitir errores de rechazo no controlados?Respuestas:
Sí, es extraño, y no debes hacer esto. No repita los arreglos de promesas, esto conduce exactamente al problema de rechazos no controlados que mencionó .
Entonces, ¿por qué se admite esto en el idioma? Para continuar con la promesa descuidada semántica.
Puede encontrar el razonamiento exacto en este comentario del tema que discute esta parte de la propuesta :
fuente
unhandledrejectioneventos?window.addEventListener('unhandledrejection',...En resumen: es la única instancia que puedo recordar, de este tipo de emisión de error por JavaScript. Sin embargo, es casi seguro que me equivoco al pensar esto. Finalmente: ¿la emisión de este "error" realmente importa más allá de tener un mensaje de error no deseado en la consola?La
sadpromesa no está siendoawaited cuando falla - que las necesidades de código para terminar la espera dehappyque pueda comenzar a esperar ensad. Lasadpromesa está fallando antes dehappyresolverse. (Promise.alles una herramienta más adecuada para este caso de uso)fuente
Promise.alles una mejor solución, ¿por qué el lenguaje atiende esta sintaxis?for await...ofpodría haberse implementado fácilmente para enumerar simplemente iterables asincrónicos. Pero se encargaron de que enumerara iterables sincrónicos (pero con una trampa (¿aparente?)). ¿Por qué?for await ... ofacepta iterables sincrónicos? Me imagino que admite generadores asíncronos que condicionalmente pueden devolver elementos sincrónicos.