await solo es válido en la función asíncrona
Escribí este código en lib/helper.js
:
var myfunction = async function(x,y) {
....
return [variableA, variableB]
}
exports.myfunction = myfunction;
Luego intenté usarlo en otro archivo:
var helper = require('./helper.js');
var start = function(a,b){
....
const result = await helper.myfunction('test','test');
}
exports.start = start;
Recibí un error:
await solo es válido en la función asíncrona
¿Cual es el problema?
El error no se refiere myfunction
sino a start
.
async function start() {
....
const result = await helper.myfunction('test', 'test');
}
// My function
const myfunction = async function(x, y) {
return [
x,
y,
];
}
// Start function
const start = async function(a, b) {
const result = await myfunction('test', 'test');
console.log(result);
}
// Call start
start();
Aprovecho la oportunidad de esta pregunta para informarle sobre un antipatrón conocido await
que es: return await
.
EQUIVOCADO
async function myfunction() {
console.log('Inside of myfunction');
}
// Here we wait for the myfunction to finish
// and then returns a promise that'll be waited for aswell
// It's useless to wait the myfunction to finish before to return
// we can simply returns a promise that will be resolved later
// useless async here
async function start() {
// useless await here
return await myfunction();
}
// Call start
(async() => {
console.log('before start');
await start();
console.log('after start');
})();
CORRECTO
async function myfunction() {
console.log('Inside of myfunction');
}
// Here we wait for the myfunction to finish
// and then returns a promise that'll be waited for aswell
// It's useless to wait the myfunction to finish before to return
// we can simply returns a promise that will be resolved later
// Also point that we don't use async keyword on the function because
// we can simply returns the promise returned by myfunction
function start() {
return myfunction();
}
// Call start
(async() => {
console.log('before start');
await start();
console.log('after start');
})();
Además, sepa que hay un caso especial en el que return await
es correcto e importante: (usando try/catch)
¿Existen problemas de rendimiento con la "espera de devolución"?
Para usarlo await
, su contexto de ejecución debe estar async
en la naturaleza.
Como se dijo, antes que nada, debes definir la naturaleza de tu executing context
disposición a realizar await
una tarea.
Simplemente colóquelo async
antes de la fn
declaración en la que async
se ejecutará su tarea.
var start = async function(a, b) {
// Your async task will execute with await
await foo()
console.log('I will execute after foo get either resolved/rejected')
}
Explicación:
var helper = require('./helper.js');
var start = async function(a,b){
....
const result = await helper.myfunction('test','test');
}
exports.start = start;
Preguntándose qué hay debajo del capó
await
consume métodos/funciones de promesa/futuro/de devolución de tareas y async
marca un método/función como capaz de usar await.
Además, si está familiarizado con promises
, await
en realidad está realizando el mismo proceso de promesa/resolución. Crea una cadena de promesa y ejecuta su próxima tarea en devolución de resolve
llamada.
Para obtener más información, puede consultar MDN DOCS .
Cuando recibí este error, resultó que tenía una llamada a la función de mapa dentro de mi función "async", por lo que este mensaje de error en realidad se refería a que la función de mapa no estaba marcada como "async". Solucioné este problema eliminando la llamada "espera" de la función de mapa e ideando otra forma de obtener el comportamiento esperado.
var myfunction = async function(x,y) {
....
someArray.map(someVariable => { // <- This was the function giving the error
return await someFunction(someVariable);
});
}
Si está escribiendo una extensión de Chrome y recibe este error en su código en la raíz, puede solucionarlo utilizando la siguiente "solución alternativa":
async function run() {
// Your async code here
const beers = await fetch("https://api.punkapi.com/v2/beers");
}
run();
Básicamente, debes envolver tu código asíncrono en un async function
y luego llamar a la función sin esperarla.