Tengo problemas para entender javaScript promises
. Escribí el siguiente código:
var p = new Promise(function(resolve,reject){
reject(Error("hello world"));
});
setTimeout(()=>p.catch(e=>console.log(e)),5000);
Inmediatamente veo esto en mi consola de desarrollador de Chrome:
Pero después de esperar 5 segundos, el mensaje cambia automáticamente a negro como esta imagen:
Nunca antes había visto este comportamiento entre mi código javaScript y una consola de desarrollador, donde mi código javaScript puede "modificar el contenido existente" en la consola de desarrollador.
Así que decidí ver si ocurre la misma situación resolve
escribiendo este código:
var p = new Promise(function(resolve,reject){
resolve("hello world");
});
setTimeout(()=>p.then(e=>console.log(e)),5000);
Pero en esta situación, mi consola de desarrollador no muestra nada hasta 5 segundos después, a lo que luego imprime hello world
.
¿Por qué las resolve
y reject
tratada de manera diferente en términos de cuando se invocan?
EXTRA
También escribí este código:
var p = new Promise(function(resolve,reject){
reject(Error("hello world"));
});
setTimeout(()=>p.catch(e=>console.log("errors",e)),5000);
setTimeout(()=>p.catch(e=>console.log("errors 2",e)),6000);
setTimeout(()=>p.catch(null),7000);
Esto provoca varias salidas a la consola del desarrollador. Error rojo en el tiempo 0, rojo cambia a negro en el tiempo 5 segundos con el texto errors hello world
, luego un nuevo mensaje de error en el tiempo 6 segundos errors 2 hello world
, luego un mensaje de error rojo en el tiempo 7 segundos. Ahora estoy muy confundido acerca de cuántas veces reject
se invoca realmente ... Estoy perdido ...
var p = new Promise(function(resolve,reject){ reject(Error("hello world")); });
puede escribirse de manera más idiomática y concisa comovar p = Promise.reject(Error("hello world"));
:-)Respuestas:
Wow, eso es realmente genial. Nunca había visto a la consola hacer eso antes. (Sin embargo, tiene otras formas de comportamiento dinámico, así que ...) Esto es lo que está sucediendo:
En el primer caso, la ejecución del código de todo lo que está fuera
setTimeout
del código de devolución de llamada se completa y la pila de ejecución regresa de modo que solo " código de plataforma se está ejecutando el " (como lo llama la especificación Promises / A +), no el código JavaScript del usuario (por el momento). En ese punto, la promesa es rechazada y nada ha manejado el rechazo, por lo que es un rechazo no manejado y devtools se lo informa como tal.Luego , cinco segundos después, su devolución de llamada se ejecuta y adjunta un controlador de rechazo. En este punto, el rechazo ya no se maneja. Aparentemente, Chrome / V8 / devtools trabajan juntos para eliminar la advertencia de rechazo no controlada de la consola. En cambio, lo que ves es lo que publicas en tu controlador de rechazo
console.log
. Si adjuntaste el controlador de rechazo antes, no obtendrías ese error de rechazo no controlado.Esto no sucede con el cumplimiento porque no manejar el cumplimiento no es una condición de error. No manejar el rechazo es.
fuente