w3schools w3school tutorial promises make for dummies create javascript promise

javascript - w3school - Constructor de promesas con rechazo de llamada vs error de lanzamiento



tutorial promises (4)

¿Hay alguna diferencia entre usar el reject (en p2 ) de la API de Promise y lanzar un error (en p1 ) usando throw ?

Sí, no cannot usar throw asincrónicamente, mientras que el reject es una devolución de llamada. Por ejemplo, un tiempo de espera:

new Promise(_, reject) { setTimeout(reject, 1000); });

¿Es exactamente lo mismo?

No, al menos no cuando otro código sigue su declaración. throw completa inmediatamente la función de resolución, mientras que llamar a reject continúa la ejecución normalmente, después de haber "marcado" la promesa como rechazada.

Además, los motores pueden proporcionar información de depuración de excepciones diferente si throw objetos de error.

Para su ejemplo específico, tiene razón en que p1 y p2 son indistinguibles del exterior.

En el siguiente código:

var p1 = new Promise(function (resolve, reject) { throw ''test1''; }); var p2 = new Promise(function (resolve, reject) { reject(''test2''); }); p1.catch(function (err) { console.log(err); // test1 }); p2.catch(function (err) { console.log(err); // test2 });

¿Hay alguna diferencia entre usar el reject (en p2 ) de la API de Promise y lanzar un error (en p1 ) usando throw ?

¿Es exactamente lo mismo?

Si es lo mismo, ¿por qué necesitamos una devolución de llamada de reject ?


No, no lo hay, los dos son completamente idénticos. La única diferencia y por qué necesitamos reject es cuando necesita rechazar de forma asincrónica; por ejemplo, si está convirtiendo una API basada en devolución de llamada, es posible que deba señalar un error asincrónico.

var p = new Promise(function(resolve, reject){ someCallbackApi(function(err, data){ if(err) reject(err); // CAN''T THROW HERE, non promise context, async. else resolve(data); }); });


Sé que esto es un poco tarde, pero realmente no creo que ninguna de estas respuestas responda por completo a las preguntas que tuve cuando encontré esto. Aquí hay un ejemplo más completo para jugar.

var p1 = new Promise(function (resolve, reject) { throw ''test 1.1''; //This actually happens console.log(''test 1.1.1''); //This never happens reject(''test 1.2''); //This never happens because throwing an error already rejected the promise console.log(''test 1.3''); //This never happens }); var p2 = new Promise(function (resolve, reject) { reject(''test 2.1''); //This actually happens console.log(''test 2.1.1''); //This happens BEFORE the Promise is rejected because reject() is a callback throw ''test 2.2''; //This error is caught and ignored by the Promise console.log(''test 2.3''); //This never happens }); var p3 = new Promise(function (resolve, reject) { setTimeout(function() { reject(''test 3.1'');}, 1000); //This never happens because throwing an error already rejected the promise throw(''test 3.2''); //This actually happens console.log(''test 3.3''); //This never happens }); var p4 = new Promise(function (resolve, reject) { throw(''test 4.1''); //This actually happens setTimeout(function() { reject(''test 4.2'');}, 1000); //This never happens because throwing an error already rejected the promise console.log(''test 4.3''); //This never happens }); var p5 = new Promise(function (resolve, reject) { setTimeout(function() { throw(''test 5.1'');}, 1000); //This throws an Uncaught Error Exception reject(''test 5.2''); //This actually happens console.log(''test 5.3''); //This happens BEFORE the Promise is rejected because reject() is a callback }); var p6 = new Promise(function (resolve, reject) { reject(''test 6.1''); //This actually happens setTimeout(function() { throw(''test 6.2'');}, 1000); //This throws an Uncaught Error Exception console.log(''test 6.3''); //This happens BEFORE the Promise is rejected because reject() is a callback }); p1.then(function (resolve) { console.log(resolve, "resolved") }, function (reject) { console.log(reject, "rejected") }).catch(function (err) { console.log(err, "caught"); // test1 }); p2.then(function (resolve) { console.log(resolve, "resolved") }, function (reject) { console.log(reject, "rejected") }).catch(function (err) { console.log(err, "caught"); // test2 }); p3.then(function (resolve) { console.log(resolve, "resolved") }, function (reject) { console.log(reject, "rejected") }).catch(function (err) { console.log(err, "caught"); // test3 }); p4.then(function (resolve) { console.log(resolve, "resolved") }, function (reject) { console.log(reject, "rejected") }).catch(function (err) { console.log(err, "caught"); // test4 }); p5.then(function (resolve) { console.log(resolve, "resolved") }, function (reject) { console.log(reject, "rejected") }).catch(function (err) { console.log(err, "caught"); // test5 }); p6.then(function (resolve) { console.log(resolve, "resolved") }, function (reject) { console.log(reject, "rejected") }).catch(function (err) { console.log(err, "caught"); // test6 });


Una observación muy interesante es que si usa throw , será manejado primero por el controlador de reject y luego el controlador de error si no hay un controlador de rechazo en su lugar.

Con bloque de manejo de rechazos

var allowed = false; var p1 = new Promise( function(resolve, reject) { if (allowed) resolve(''Success''); else // reject(''Not allowed''); throw new Error(''I threw an error'') }) p1.then(function(fulfilled) { console.log(''Inside resolve handler, resolved value: '' + fulfilled); }, function(rejected) { console.log(''Inside reject handler, rejected value: '' + rejected); }).catch(function(error) { console.log(''Inside error handler, error value: '' + error); })

Sin bloque de manejo de rechazo

var allowed = false; var p1 = new Promise( function(resolve, reject) { if (allowed) resolve(''Success''); else // reject(''Not allowed''); throw new Error(''I threw an error'') }) p1.then(function(fulfilled) { console.log(''Inside resolve handler, resolved value: '' + fulfilled); }).catch(function(error) { console.log(''Inside error handler, error value: '' + error); })

Además, el bloque catch podrá detectar cualquier error arrojado dentro del controlador de resolve .

var allowed = true; var p1 = new Promise( function(resolve, reject) { if (allowed) resolve(''Success''); else // reject(''Not allowed''); throw new Error(''I threw an error'') }) p1.then(function(fulfilled) { console.log(''Inside resolve handler, resolved value: '' + fulfilled); throw new Error(''Error created inside resolve handler block''); }).catch(function(error) { console.log(''Inside error handler, error value: '' + error); })

Parece que es mejor usar throw , a menos que no pueda si está ejecutando alguna tarea asincrónica, tendrá que pasar la devolución de llamada de reject a la función asincrónica. Pero hay una solución, que es promisificar su función asíncrona. Más en https://.com/a/33446005