¿Cómo puedo rechazar una promesa devuelta por una función asíncrona / espera?
por ejemplo, originalmente
foo(id: string): Promise<A> {
return new Promise((resolve, reject) => {
someAsyncPromise().then((value)=>resolve(200)).catch((err)=>reject(400))
});
}
Traducir a asíncrono / esperar
async foo(id: string): Promise<A> {
try{
await someAsyncPromise();
return 200;
} catch(error) {//here goes if someAsyncPromise() rejected}
return 400; //this will result in a resolved promise.
});
}
Entonces, ¿cómo podría rechazar adecuadamente esta promesa en este caso?

Promiseconstructor antipatrón ! Incluso el primer fragmento debería haberse escritofoo(id: string): Promise<A> { return someAsyncPromise().then(()=>{ return 200; }, ()=>{ throw 400; }); }Respuestas:
Su mejor apuesta es
throwunaErrorenvoltura del valor, lo que resulta en una promesa rechazada con unaErrorenvoltura del valor:También puede solo
throwel valor, pero no hay información de seguimiento de la pila:Alternativamente, devuelva una promesa rechazada con una
Errorenvoltura del valor, pero no es idiomático:(O simplemente
return Promise.reject(400);, pero de nuevo, entonces no hay información de contexto).(En su caso, como está usando
TypeScriptyfooel valor de recuperación esPromise<A>, usaríareturn Promise.reject<A>(400 /*or error*/);)En una situación
async/await, ese último es probablemente un poco de coincidencia semántica, pero funciona.Si arroja un
Error, eso juega bien con cualquier cosa que consuma elfooresultado de suawaitsintaxis:fuente
throwes mejor quePromise.reject()IMO. Sithrow 400es una pregunta diferente. En el OP está rechazando 400, y podemos argumentar que debería rechazar unErroren su lugar.asyncfunciones, no hayresolveorejectfunción. Hayreturnythrow, cuáles son las formas idiomáticas de resolver y rechazar laasyncpromesa de la función.newhace explícito. También tenga en cuenta que no puede dejarlo fuera si tiene unaErrorsubclase (class MyError extends Error), así que ...Probablemente también debería mencionarse que simplemente puede encadenar una
catch()función después de la llamada de su operación asincrónica porque, bajo el capó, aún se devuelve una promesa.De esta forma, puede evitar la
try/catchsintaxis si no le gusta.fuente
asyncfunción, lanzo una excepción y luego la atrapo muy bien,.catch()como si volvieraPromise.rejecto llamarareject. ¡Me gusta!awaitfallas posibles en una rutina. A menos que se necesiten casos muy específicos para cada unoawait, no veo por qué querría atraparlos así. Solo yo humilde opinión.awaitfalla por separado, sino que también necesitaba trabajar con un marco basado en Promise que rechazara las promesas por error.${host}/user/permissions/repositories_wrong_url/, accessToken, accessTokenSecret) .catch (err => {logger.error ('No se pueden recuperar los permisos del repositorio', err); devolución de llamada (err);})awaitpalabra clave aquí.Puede crear una función de contenedor que promete y devuelve una matriz con datos si no hay error y el error si hubo un error.
Úselo así en ES7 y en una función asíncrona :
fuente
Una mejor manera de escribir la función asíncrona sería devolviendo una Promesa pendiente desde el principio y luego manejando tanto los rechazos como las resoluciones dentro de la devolución de llamada de la promesa, en lugar de escupir una promesa rechazada por error. Ejemplo:
Luego, solo encadena métodos en la promesa devuelta:
Fuente: este tutorial:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
fuente
Tengo una sugerencia para manejar adecuadamente los rechazos en un enfoque novedoso, sin tener múltiples bloques try-catch.
Donde se debe importar la función to.ts desde:
Los créditos van a Dima Grossman en el siguiente enlace .
fuente
let [err]=si solo busca errores.Esta no es una respuesta sobre la de @TJ Crowder. Solo un comentario que responde al comentario "Y, de hecho, si la excepción se convertirá en un rechazo, no estoy seguro de si realmente me molesta si se trata de un error. Mis razones para arrojar solo el error probablemente no se apliquen. "
si su código está usando
async/await, entonces es una buena práctica rechazar con un enErrorlugar de400:fuente
Sé que esta es una vieja pregunta, pero acabo de tropezar con el hilo y parece haber una confusión entre errores y rechazo que entra en conflicto (al menos en muchos casos) con los consejos que se repiten a menudo para no usar el manejo de excepciones para lidiar con casos anticipados. Para ilustrar: si un método asincrónico está intentando autenticar a un usuario y la autenticación falla, es un rechazo (uno de los dos casos previstos) y no un error (por ejemplo, si la API de autenticación no estaba disponible).
Para asegurarme de que no solo estaba dividiendo pelos, realicé una prueba de rendimiento de tres enfoques diferentes para eso, usando este código:
Algunas de las cosas que están allí están incluidas debido a mi incertidumbre con respecto al intérprete de Javascript (solo me gusta ir por una madriguera a la vez); por ejemplo, incluí la
doSomethingfunción y asigné su retorno adummyValuepara garantizar que los bloques condicionales no se optimizaran.Mis resultados fueron:
Sé que hay muchos casos en los que no vale la pena buscar pequeñas optimizaciones, pero en sistemas a gran escala, estas cosas pueden hacer una gran diferencia acumulativa, y esa es una comparación bastante dura.
ASÍ… aunque creo que el enfoque de la respuesta aceptada es sólido en los casos en que espera tener que manejar errores impredecibles dentro de una función asincrónica, en los casos en que un rechazo simplemente significa "tendrá que seguir el Plan B (o C o D ...) "Creo que mi preferencia sería rechazar el uso de un objeto de respuesta personalizado.
fuente