valid uncaught try syntaxerror only funciona example como catch await async javascript node.js async-await ecmascript-2017

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:

  1. Utilice una función async nivel superior que nunca rechace (a menos que desee errores de "rechazo no controlado"), o

  2. Use then y catch , o

  3. (¡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 de await 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:

  1. No use await directamente dentro de la función
  2. 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] .