Sabemos que las funciones async devuelven una Promesa implícitamente. Pero tengo una pregunta puramente pedante. ¿Debo poner una palabra clave async si devuelvo una Promesa explícitamente?
Es esto:
const wait = async ms => new Promise( resolve => setTimeout(resolve, ms) );¿Algo diferente a esto?
const wait = ms => new Promise( resolve => setTimeout(resolve, ms) );Creo que técnicamente son idénticos. ¿Hay alguna guía de estilo o recomendación oficial detrás de alguna de estas dos formas de definir este tipo de función?
Hay cuatro razones principales en las que pienso para usar funciones async :
await .async deja en claro a las personas que llaman que miran el código que la función siempre devuelve una promesa, esencialmente autodocumentada. Entonces, si no está usando await y no necesita el punto n. ° 2 y ya está devolviendo manualmente una promesa, entonces realmente no hay ningún requisito para declarar la función como async .
Algunas reflexiones más sobre los puntos anteriores.
El punto n. ° 1 requiere async si va a usar await . No hay otra forma de evitarlo.
Los puntos n.° 2 y n.° 3 son realmente solo conveniencias de programación. Si detecta sus propias excepciones síncronas o está seguro de que no hay excepciones síncronas y está controlando todas las rutas de código para devolver una promesa, entonces la async no es necesaria.
Ambos puntos #2 y #3 pueden surgir si su código tiene una ruta de código síncrona y una ruta de código asíncrona, como verificar un caché y devolver un valor si está presente en el caché y, si no está en el caché, entonces haga un Solicitud de red para obtener el valor. Como se describió anteriormente, esto se puede codificar manualmente sin async , pero el código a veces puede ser un poco más simple con async porque detectará automáticamente sus excepciones sincrónicas y envolverá automáticamente un valor de retorno en una promesa.
El punto #4 es solo una preferencia de estilo de codificación. Si le gustan los aspectos de "autodocumentación" de hacer que la función sea async , puede hacerlo como una indicación de que siempre devuelve una promesa.
Y, para cualquier persona interesada en una gran cantidad de detalles técnicos sobre cómo funcionan internamente las funciones async y cómo se han optimizado a lo largo de los años, este es un artículo bastante detallado sobre el tema: Blog V8 sobre asíncronismo rápido .
En el ejemplo dado, la palabra clave async esencialmente solo envuelve el valor devuelto en Promise.resolve() . Consulte la documentación de la función asíncrona .
Así que por un lado tienes:
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));Mientras que por el otro tienes:
const wait = async ms => new Promise(resolve => setTimeout(resolve, ms)); // is similar to const wait = ms => Promise.resolve(new Promise(resolve => setTimeout(resolve, ms))); Son esencialmente lo mismo y personalmente optaría por la variante sin la palabra clave async .
Nota:
Aunque el valor de retorno de una función asíncrona se comporta como si estuviera envuelto en
Promise.resolve, no son equivalentes.Una función asíncrona devolverá una referencia diferente, mientras que
Promise.resolvedevolverá la misma referencia si el valor dado es una promesa.Puede ser un problema cuando desea verificar la igualdad de una promesa y un valor de retorno de una función asíncrona.
const p = new Promise((res, rej) => { res(1); }) async function asyncReturn() { return p; } function basicReturn() { return Promise.resolve(p); } console.log(p === basicReturn()); // true console.log(p === asyncReturn()); // false