uncaught - promise javascript
¿Cómo puedo usar async/await en el nivel superior? (5)
Parece que no puedo entender por qué esto no funciona.
Porque
main
devuelve una promesa;
todas las funciones
async
hacen.
En el nivel superior, debes:
-
Utilice una función
async
nivel superior que nunca rechace (a menos que desee errores de "rechazo no controlado"), o -
Use
then
ycatch
, o -
(¡Próximamente!) Use el nivel superior de
await
, una propuesta que ha alcanzado la Etapa 3 en el process que permite el uso de nivel superior deawait
en un módulo.
# 1 - Función
async
nivel superior que nunca rechaza
(async () => {
try {
var text = await main();
console.log(text);
} catch (e) {
// Deal with the fact the chain failed
}
})();
Observe la
catch
;
debe
manejar los rechazos de promesas / excepciones asíncronas, ya que nada más lo
hará
;
no tienes que llamar para pasarlos.
Si lo prefiere, puede hacerlo con el resultado de llamarlo a través de la función
catch
(en lugar de la sintaxis
try
/
catch
):
(async () => {
var text = await main();
console.log(text);
})().catch(e => {
// Deal with the fact the chain failed
});
... que es un poco más conciso (por eso me gusta).
O, por supuesto, no maneje los errores y solo permita el error de "rechazo no controlado".
# 2 -
then
y
catch
main()
.then(text => {
console.log(text);
})
.catch(err => {
// Deal with the fact the chain failed
});
Se llamará al controlador
catch
si se producen errores en la cadena o en su controlador
then
.
(Asegúrese de que su controlador de
catch
no arroje errores, ya que no hay nada registrado para manejarlos).
O ambos argumentos para
then
:
main().then(
text => {
console.log(text);
},
err => {
// Deal with the fact the chain failed
}
);
Nuevamente, observe que estamos registrando un controlador de rechazo. Pero de esta forma, asegúrese de que ninguna de sus devoluciones de llamada no arroje ningún error, no hay nada registrado para manejarlos.
# 3 de nivel superior
await
en un módulo
No puede usar el modo de
await
en el nivel superior de un script que no sea de módulo, pero la propuesta de nivel superior de
await
permite usarlo en el nivel superior de un módulo.
Es similar a usar una envoltura de función
async
nivel superior (# 1 arriba) en que no desea que su código de nivel superior rechace (arroje un error) porque eso dará como resultado un error de rechazo no controlado.
Entonces, a menos que desee tener ese rechazo no controlado cuando las cosas salen mal, como con el n. ° 1, querrá incluir su código en un controlador de errores:
// In a module, once the top-level `await` proposal lands
try {
var text = await main();
console.log(text);
} catch (e) {
// Deal with the fact the chain failed
}
He estado revisando async / wait y después de revisar varios artículos, decidí probar las cosas por mí mismo. Sin embargo, parece que no puedo entender por qué esto no funciona:
async function main() {
var value = await Promise.resolve(''Hey there'');
console.log(''inside: '' + value);
return value;
}
var text = main();
console.log(''outside: '' + text)
La consola genera lo siguiente (nodo v8.6.0):
> afuera: [Promesa del objeto]
> dentro: Hola
¿Por qué el mensaje de registro dentro de la función se ejecuta después? Pensé que la razón por la que se creó async / await fue para realizar una ejecución sincrónica utilizando tareas asincrónicas.
¿Hay alguna forma de usar el valor devuelto dentro de la función sin usar
.then()
después de
main()
?
Como
main()
ejecuta de forma asincrónica, devuelve una promesa.
Tienes que obtener el resultado en el método
then()
.
Y como
then()
devuelve la promesa también, debe llamar a
process.exit()
para finalizar el programa.
main()
.then(
(text) => { console.log(''outside: '' + text) },
(err) => { console.log(err) }
)
.then(() => { process.exit() } )
La solución real a este problema es abordarlo de manera diferente.
Probablemente su objetivo es algún tipo de inicialización que generalmente ocurre en el nivel superior de una aplicación.
La solución es garantizar que solo haya una única declaración de JavaScript en el nivel superior de su aplicación. Si solo tiene una declaración en la parte superior de su aplicación, puede usar async / wait en cualquier otro lugar (sujeto a las reglas de sintaxis normales)
Dicho de otra manera, envuelva todo su nivel superior en una función para que ya no sea el nivel superior y eso resuelva la cuestión de cómo ejecutar async / wait en el nivel superior de una aplicación, no lo hace.
Así debería verse el nivel superior de su aplicación:
import {application} from ''./server''
application();
Para dar más información sobre las respuestas actuales:
El contenido de un archivo
node.js
se concatena actualmente, de forma similar a una cadena, para formar un cuerpo de función.
Por ejemplo, si tiene un archivo
test.js
:
// Amazing test file!
console.log(''Test!'');
Entonces
node.js
secretamente concatenará una función que se ve así:
function(require, __dirname, ... a bunch more top-level properties) {
// Amazing test file!
console.log(''test!'');
}
Lo más importante a tener en cuenta es que la función resultante NO es una función asíncrona.
¡Entonces no puedes usar el término
await
directamente dentro de él!
Pero supongamos que necesita trabajar con las promesas en este archivo, entonces hay dos métodos posibles:
-
No use
await
directamente dentro de la función -
No use
await
La opción 1 requiere que creemos un nuevo alcance (y ESTE alcance puede ser
async
, porque tenemos control sobre él):
// Amazing test file!
// Create a new async function (a new scope) and immediately call it!
(async () => {
await new Promise(...);
console.log(''Test!'');
})();
La opción 2 requiere que usemos la API de promesa orientada a objetos (el paradigma menos bonito pero igualmente funcional de trabajar con promesas)
// Amazing test file!
// Create some sort of promise...
let myPromise = new Promise(...);
// Now use the object-oriented API
myPromise.then(() => console.log(''Test!''));
Personalmente espero que, si es viable, node.js concatene el código por defecto en una función
async
.
Eso eliminaría este dolor de cabeza.
La
await
nivel superior se
ha movido a la etapa 3, por lo que la respuesta a su pregunta
¿Cómo puedo usar async / wait en el nivel superior?
es simplemente agregar
await
la llamada a
main()
:
async function main() {
var value = await Promise.resolve(''Hey there'');
console.log(''inside: '' + value);
return value;
}
var text = await main();
console.log(''outside: '' + text)
O solo:
const text = await Promise.resolve(''Hey there'');
console.log(''outside: '' + text)
Tenga en cuenta que todavía solo está disponible en [email protected] .