Leí que las funciones asíncronas marcadas por la async
palabra clave devuelven implícitamente una promesa:
async function getVal(){
return await doSomethingAync();
}
var ret = getVal();
console.log(ret);
pero eso no es coherente ... asumiendo que doSomethingAsync()
devuelve una promesa, y la palabra clave await devolverá el valor de la promesa, no la promesa en sí, entonces mi función getVal debería devolver ese valor, no una promesa implícita.
Entonces, ¿cuál es exactamente el caso? ¿Las funciones marcadas por la palabra clave async devuelven promesas implícitamente o controlamos lo que devuelven?
¿Quizás si no devolvemos algo explícitamente, entonces devuelven implícitamente una promesa ...?
Para ser más claro, existe una diferencia entre lo anterior y
function doSomethingAync(charlie) {
return new Promise(function (resolve) {
setTimeout(function () {
resolve(charlie || 'yikes');
}, 100);
})
}
async function getVal(){
var val = await doSomethingAync(); // val is not a promise
console.log(val); // logs 'yikes' or whatever
return val; // but this returns a promise
}
var ret = getVal();
console.log(ret); //logs a promise
En mi sinopsis, el comportamiento es de hecho inconsistente con las declaraciones de devolución tradicionales. Parece que cuando devuelve explícitamente un valor no prometido de una async
función, lo forzará a envolverlo en una promesa. No tengo un gran problema con él, pero desafía al JS normal.
fuente
console.log
muestra?Respuestas:
El valor de retorno siempre será una promesa. Si no devuelve explícitamente una promesa, el valor que devuelva se incluirá automáticamente en una promesa.
Lo mismo incluso si hay un
await
.Promesas que se desenvuelven automáticamente, por lo que si devuelve una promesa por un valor desde dentro de una
async
función, recibirá una promesa por el valor (no una promesa por una promesa por el valor).ES6 tiene funciones que no devuelven exactamente el mismo valor que el
return
. Estas funciones se denominan generadores.fuente
Eché un vistazo a la especificación y encontré la siguiente información. La versión corta es que an
async function
desugars a un generador que producePromise
s. Entonces, sí, las funciones asíncronas devuelven promesas .Según la especificación tc39 , se cumple lo siguiente:
Azúcares para:
Donde
spawn
"es una llamada al siguiente algoritmo":fuente
async function
conasync function*
. El primero simplemente devuelve una promesa. Este último devuelve un generador que rinde promesas.Simplemente agregue await antes de su función cuando la llame:
fuente
async no devuelve la promesa, la palabra clave await espera la resolución de la promesa. async es una función de generador mejorada y await funciona un poco como yield
Creo que la sintaxis (no estoy 100% seguro) es
async function* getVal() {...}
Las funciones del generador ES2016 funcionan un poco así. He creado un controlador de base de datos basado en tedioso que programa así
Observe cómo lo programo como sincrónico normal, particularmente en
yield connection.execSql
y enyield connection.callProcedure
La función db.exec es un generador basado en Promesas bastante típico
fuente