Cómo escribir código asincrónico en Node.js

6 mar 2021 15 min di lettura
Cómo escribir código asincrónico en Node.js
Indice dei contenuti

Introducción

Para muchos programas JavaScript, el código se ejecuta como lo escribe el desarrollador, línea por línea. A esto se le llama ejecución síncrona, porque las líneas se ejecutan una tras otra, en el orden en que fueron escritas. Sin embargo, no es necesario seguir inmediatamente todas las instrucciones dadas a la computadora. Por ejemplo, si envía una solicitud de red, el proceso que ejecuta el código tendrá que esperar a que se devuelvan los datos antes de que pueda ejecutarse en él. En este caso, se desperdiciaría tiempo si no ejecutara otro código esperando a que se completara la solicitud de red. Para resolver este problema, los desarrolladores utilizan programación asincrónica, en la que las líneas de código se ejecutan en un orden diferente al que se escribieron.

El código JavaScript se ejecuta en un solo hilo dentro de un proceso informático. Su código se procesa sincrónicamente en este hilo, con solo una instrucción que se ejecuta a la vez. Por lo tanto, si tuviéramos que realizar una tarea de larga duración en este hilo, todo el código restante se bloquea hasta que se complete la tarea. Aprovechando las capacidades de programación asincrónica de JavaScript, podemos descargar tareas de larga duración a un hilo en segundo plano para evitar este problema. Cuando se completa la actividad, el código que necesitamos para procesar los datos de la actividad se devuelve al hilo principal único.

Prerrequisitos

  • Node.js instalado en la máquina de desarrollo.

L'Event Loop

Comencemos por estudiar el funcionamiento interno de ejecutar la función JavaScript. Comprender cómo se comporta esto le permitirá escribir código asincrónico de manera más deliberada y lo ayudará a solucionar problemas de código en el futuro.

Cuando el intérprete de JavaScript ejecuta el código, cada función llamada se agrega a la pila de llamadas de JavaScript. La pila de llamadas es una pila, una estructura de datos similar a una lista en la que los elementos solo se pueden agregar a la parte superior y eliminar de la parte superior. Las pilas siguen el principio "Último en entrar, primero en salir" o LIFO. Si agrega dos elementos a la pila, primero se elimina el elemento agregado más recientemente.

Ilustremos con un ejemplo usando la pila de llamadas. Si JavaScript detecta una función llamada functionA(), se agrega a la pila de llamadas. Si esa función functionA()llama a otra función functionB(), se functionB()agrega a la parte superior de la pila de llamadas. Cuando JavaScript completa la ejecución de una función, se elimina de la pila de llamadas. Por lo tanto, JavaScript se ejecutará primero functionB(), lo eliminará de la pila cuando termine, luego terminará la ejecución functionA()y lo eliminará de la pila de llamadas. Es por eso que las funciones internas siempre se ejecutan antes que sus funciones externas.

Cuando JavaScript encuentra una operación asincrónica, como escribir en un archivo, lo agrega a una tabla en su memoria. Esta tabla almacena la operación, la condición para su finalización y la función a llamar cuando se complete. Cuando finaliza, JavaScript agrega la función asociada a la cola de mensajes. Una cola es otra estructura de datos similar a una lista en la que los elementos solo se pueden agregar en la parte inferior pero eliminarlos en la parte superior. En la cola de mensajes, si dos o más operaciones asíncronas están listas para realizar sus funciones, la operación asíncrona completada primero tendrá su función marcada para su ejecución en primer lugar.

Las funciones en la cola de mensajes están esperando ser agregadas a la pila de llamadas. El bucle de eventos es un proceso perpetuo que comprueba si la pila de llamadas está vacía. En este caso, el primer elemento de la cola de mensajes se mueve a la pila de llamadas. JavaScript da prioridad a las funciones en la cola de mensajes sobre las llamadas a funciones que interpreta en el código. El efecto combinado de la pila de llamadas, la cola de mensajes y el bucle de eventos permite procesar JavaScript cuando se manejan tareas asincrónicas.

Ahora que tiene una comprensión de alto nivel del bucle de eventos, sabe cómo se ejecutará el código asincrónico que escriba. Con este conocimiento, ahora puede crear código asincrónico con tres enfoques diferentes: devoluciones de llamada, promesas y async/ await.

Programación asincrónica con devoluciones de llamada

Una función de devolución de llamada es aquella que se pasa como argumento a otra función y luego se ejecuta cuando la otra función finaliza. Usamos devoluciones de llamada para asegurarnos de que el código solo se ejecute después de completar una operación asincrónica.

Durante mucho tiempo, las devoluciones de llamada han sido el mecanismo más común para escribir código asincrónico, pero ahora se han vuelto obsoletos porque pueden hacer que el código sea ilegible. En este paso, escribirá un ejemplo de código asincrónico usando devoluciones de llamada para que pueda usarlo como base para ver la mayor eficiencia de otras estrategias.

Hay muchas formas de utilizar las funciones de devolución de llamada en otra función. Generalmente, toman esta estructura:

function asynchronousFunction([ Function Arguments ], [ Callback Function ]) {
    [ Action ]
}

Si bien JavaScript o Node.js no requieren sintácticamente que la función de devolución de llamada sea el último argumento de la función externa, es una práctica común que facilita la identificación de las devoluciones de llamada. También es común que los desarrolladores de JavaScript utilicen una función anónima, como una devolución de llamada. Las funciones anónimas son aquellas creadas sin nombre. Suele ser mucho más legible cuando se define una función al final de la lista de argumentos.

Para demostrar las devoluciones de llamada, creemos un módulo Node.js que escriba una lista de películas de Studio Ghibli en un archivo. Primero, cree una carpeta que almacenará nuestro archivo JavaScript y su salida con el comando mkdir :

mkdir ghibliMovies

Luego acceda a la carpeta con el comando cd :

cd ghibliMovies

Comenzaremos haciendo una solicitud HTTP a la API de Studio Ghibli , de la cual nuestra función de devolución de llamada registrará los resultados. Para ello, instalaremos una librería que nos permitirá acceder a los datos de una respuesta HTTP en una devolución de llamada.

En su terminal, inicialice npm para que pueda tener una referencia para nuestros paquetes más adelante:

npm init -y

Luego, instale la biblioteca request:

npm i request --save

Ahora abra un nuevo archivo llamado callbackMovies.jsen un editor de texto como nano:

nano callbackMovies.js

En su editor de texto, ingrese el siguiente código. Comencemos enviando una solicitud HTTP con el formulario request:

const request = require('request');

request('https://ghibliapi.herokuapp.com/films');
callbackMovies.js

En la primera línea, requestcargamos el módulo que se instaló a través de npm. El módulo devuelve una función que puede realizar solicitudes HTTP; luego guardamos esa función en la constante request.

Luego hacemos la solicitud HTTP usando la función request(). Imprimamos ahora los datos de la solicitud HTTP a la consola agregando los cambios resaltados:

const request = require('request');

request('https://ghibliapi.herokuapp.com/films', (error, response, body) => {
    if (error) {
        console.error(`Could not send request to API: ${error.message}`);
        return;
    }

    if (response.statusCode != 200) {
        console.error(`Expected status code 200 but received ${response.statusCode}.`);
        return;
    }

    console.log('Processing our list of movies');
    movies = JSON.parse(body);
    movies.forEach(movie => {
        console.log(`${movie['title']}, ${movie['release_date']}`);
    });
});
callbackMovies.js

Cuando usamos la llamada request(), le damos dos parámetros:

  • La URL del sitio web que intentamos solicitar.
  • Una función de devolución de llamada que maneja cualquier error o respuesta exitosa después de que se completa la solicitud.

Nuestra función de devolución de llamada tiene tres argumentos: error, response, y body. Cuando se completa la solicitud HTTP, a los argumentos se les asignan valores automáticamente en función del resultado. Si el envío de la solicitud falla, contendría un objeto error, pero responsey lo bodyserían null. Si la solicitud se realizó correctamente, la respuesta HTTP se almacena en formato response. Si nuestra respuesta HTTP devuelve datos (en este ejemplo obtenemos JSON), los datos se establecen en body.

Nuestra función de devolución de llamada primero verifica si hemos recibido un error. Es una buena idea verificar primero una devolución de llamada en busca de errores para que la ejecución de la devolución de llamada no continúe con datos faltantes. En este caso, registramos el error y la ejecución de la función. Luego verificamos el código de estado de la respuesta. Es posible que nuestro servidor no siempre esté disponible y las API pueden cambiar, lo que hace que las solicitudes que alguna vez sean sensibles se vuelvan incorrectas. Al verificar que el código de estado sea 200, lo que significa que la solicitud fue "OK", podemos estar seguros de que nuestra respuesta es la que esperamos.

Finalmente, analizamos el cuerpo de la respuesta a Arrayay repetimos cada película para registrar su nombre y año de lanzamiento.

Después de guardar y cerrar el archivo, ejecute este script con:

node callbackMovies.js

Obtendrá el siguiente resultado:

Castle in the Sky, 1986
Grave of the Fireflies, 1988
My Neighbor Totoro, 1988
Kiki's Delivery Service, 1989
Only Yesterday, 1991
Porco Rosso, 1992
Pom Poko, 1994
Whisper of the Heart, 1995
Princess Mononoke, 1997
My Neighbors the Yamadas, 1999
Spirited Away, 2001
The Cat Returns, 2002
Howl's Moving Castle, 2004
Tales from Earthsea, 2006
Ponyo, 2008
Arrietty, 2010
From Up on Poppy Hill, 2011
The Wind Rises, 2013
The Tale of the Princess Kaguya, 2013
When Marnie Was There, 2014

Hemos recibido con éxito una lista de películas de Studio Ghibli con el año en que fueron lanzadas. Ahora completemos este programa escribiendo la lista de películas que estamos grabando actualmente en un archivo.

Actualice el archivo callbackMovies.jsen su editor de texto para incluir el siguiente código resaltado, que crea un archivo CSV con los datos de nuestra película:

const request = require('request');
const fs = require('fs');

request('https://ghibliapi.herokuapp.com/films', (error, response, body) => {
    if (error) {
        console.error(`Could not send request to API: ${error.message}`);
        return;
    }

    if (response.statusCode != 200) {
        console.error(`Expected status code 200 but received ${response.statusCode}.`);
        return;
    }

    console.log('Processing our list of movies');
    movies = JSON.parse(body);
    let movieList = '';
    movies.forEach(movie => {
        movieList += `${movie['title']}, ${movie['release_date']}\n`;
    });

    fs.writeFile('callbackMovies.csv', movieList, (error) => {
        if (error) {
            console.error(`Could not save the Ghibli movies to a file: ${error}`);
            return;
        }

        console.log('Saved our list of movies to callbackMovies.csv');;
    });
});
callbackMovies.js

Al notar los cambios resaltados, vemos que importamos el módulo fs. Este módulo es estándar en todas las instalaciones de Node.js y contiene un método writeFile()que puede escribir de forma asincrónica en un archivo.

En lugar de registrar los datos en la consola, ahora los agregamos a una variable de cadena movieList. Entonces usamos writeFile()para guardar el contenido de movieListen un nuevo archivo - callbackMovies.csv. Por último, proporcionamos una llamada de retorno para la función writeFile(), que tiene un argumento: error. Esto nos permite manejar casos en los que no podemos escribir en un archivo, como cuando el usuario en el que estamos ejecutando el proceso nodeno tiene esos permisos.

Guarde el archivo y ejecute este programa Node.js nuevamente con:

node callbackMovies.js

En su carpeta ghibliMovies, verá callbackMovies.csv, que tiene el siguiente contenido:

Castle in the Sky, 1986
Grave of the Fireflies, 1988
My Neighbor Totoro, 1988
Kiki's Delivery Service, 1989
Only Yesterday, 1991
Porco Rosso, 1992
Pom Poko, 1994
Whisper of the Heart, 1995
Princess Mononoke, 1997
My Neighbors the Yamadas, 1999
Spirited Away, 2001
The Cat Returns, 2002
Howl's Moving Castle, 2004
Tales from Earthsea, 2006
Ponyo, 2008
Arrietty, 2010
From Up on Poppy Hill, 2011
The Wind Rises, 2013
The Tale of the Princess Kaguya, 2013
When Marnie Was There, 2014
callbackMovies.csv

Es importante tener en cuenta que escribimos en nuestro archivo CSV en la devolución de llamada de la solicitud HTTP. Una vez que el código está en la función de devolución de llamada, se escribirá en el archivo solo después de que se complete la solicitud HTTP. Si quisiéramos comunicarnos con una base de datos después de escribir nuestro archivo CSV, crearíamos otra función asincrónica que se llamaría en la devolución de llamada de writeFile(). Cuanto más código asincrónico tengamos, más funciones de devolución de llamada deben anidarse.

Imaginemos que queremos realizar cinco operaciones asincrónicas, cada una de las cuales puede realizarse solo cuando la otra está completa. Si tuviéramos que codificarlo, tendríamos algo como esto:

doSomething1(() => {
    doSomething2(() => {
        doSomething3(() => {
            doSomething4(() => {
                doSomething5(() => {
                    // final action
                });
            });
        });
    });
});

Cuando las devoluciones de llamada anidadas tienen muchas líneas de código para ejecutar, se vuelven sustancialmente más complejas e ilegibles. A medida que su proyecto de JavaScript crezca en tamaño y complejidad, este efecto se hará más pronunciado, hasta que finalmente sea inmanejable. Por esta razón, los desarrolladores ya no usan devoluciones de llamada para manejar operaciones asincrónicas. Para mejorar la sintaxis de nuestro código asincrónico, podemos usar promesas en su lugar.

Usar promesas para una programación asincrónica concisa

Una promesa es un objeto de JavaScript que devolverá un valor en el futuro. Las funciones asincrónicas pueden devolver objetos prometidos en lugar de valores concretos. Si obtenemos valor en el futuro, decimos que se ha cumplido la promesa. Si obtenemos un error en el futuro, decimos que la promesa ha sido rechazada. De lo contrario, la promesa aún se está procesando en un estado pendiente.

Las promesas generalmente adoptan la siguiente forma:

promiseFunction()
    .then([ Callback Function for Fulfilled Promise ])
    .catch([ Callback Function for Rejected Promise ])

Como se muestra en este modelo, las promesas también usan funciones de devolución de llamada. Tenemos una función de devolución de llamada para el método then(), que se ejecuta cuando se mantiene una promesa. También tenemos una función de devolución de llamada para que el método catch()maneje cualquier error que ocurra mientras se ejecuta la promesa.

Experimentamos las promesas de primera mano al reescribir nuestro programa Studio Ghibli para usar las promesas en su lugar.

Axios es un cliente HTTP basado en promesas para JavaScript, así que vamos a instalarlo:

npm i axios --save

Ahora, con su editor de texto favorito, cree un nuevo archivo promiseMovies.js:

nano promiseMovies.js

Nuestro programa hará una solicitud HTTP con axiosy luego usará una versión especial basada en la promesa de fsguardar en un nuevo archivo CSV.

Escriba este código promiseMovies.jspara que podamos cargar Axios y enviar una solicitud HTTP a la API de la película:

const axios = require('axios');

axios.get('https://ghibliapi.herokuapp.com/films');
promiseMovies.js

En la primera línea cargamos el módulo axios, almacenando la función devuelta en una llamada constante axios. Luego usamos el método axios.get()para enviar una solicitud HTTP a la API.

El método axios.get()devuelve una promesa. Encadenamos esa promesa para que podamos imprimir la lista de películas de Ghibli en la consola:

const axios = require('axios');
const fs = require('fs').promises;


axios.get('https://ghibliapi.herokuapp.com/films')
    .then((response) => {
        console.log('Successfully retrieved our list of movies');
        response.data.forEach(movie => {
            console.log(`${movie['title']}, ${movie['release_date']}`);
        });
    })
promiseMovies.js

Analicemos lo que está pasando. Después de realizar una solicitud HTTP GET con axios.get(), usamos la función then(), que solo se ejecuta cuando se mantiene la promesa. En este caso, imprimimos las películas en la pantalla como hicimos en el ejemplo de devolución de llamada.

Para mejorar este programa, agregue código resaltado para escribir datos HTTP en un archivo:

const axios = require('axios');
const fs = require('fs').promises;


axios.get('https://ghibliapi.herokuapp.com/films')
    .then((response) => {
        console.log('Successfully retrieved our list of movies');
        let movieList = '';
        response.data.forEach(movie => {
            movieList += `${movie['title']}, ${movie['release_date']}\n`;
        });

        return fs.writeFile('promiseMovies.csv', movieList);
    })
    .then(() => {
        console.log('Saved our list of movies to promiseMovies.csv');
    })
promiseMovies.js

Además, importemos el módulo nuevamente fs. Tenga en cuenta cómo después de la importación fstenemos .promises. Node.js incluye una versión prometida fsde la biblioteca basada en devolución de llamada, por lo que la compatibilidad con versiones anteriores no se rompe en proyectos heredados.

La primera función then()que procesa la solicitud HTTP ahora llama en fs.writeFile()lugar de imprimir en la consola. Dado que importamos la versión prometida de fs, nuestra función writeFile()devuelve otra promesa. Como tal, agreguemos otra función then()para cuando writeFile()se cumpla la promesa .

Una promesa puede devolver una nueva promesa, lo que nos permite cumplir promesas una tras otra. Esto nos abre el camino para realizar más operaciones asincrónicas. Esto se denomina encadenamiento de promesas y es análogo al anidamiento de devolución de llamada. El segundo then()se llama solo después de escribir correctamente en el archivo.

Para completar este programa, encadena la promesa con una función catch()como se destaca a continuación:

const axios = require('axios');
const fs = require('fs').promises;


axios.get('https://ghibliapi.herokuapp.com/films')
    .then((response) => {
        console.log('Successfully retrieved our list of movies');
        let movieList = '';
        response.data.forEach(movie => {
            movieList += `${movie['title']}, ${movie['release_date']}\n`;
        });

        return fs.writeFile('promiseMovies.csv', movieList);
    })
    .then(() => {
        console.log('Saved our list of movies to promiseMovies.csv');
    })
    .catch((error) => {
        console.error(`Could not save the Ghibli movies to a file: ${error}`);
    });
promiseMovies.js

Si alguna promesa no se mantiene en la cadena de promesas, JavaScript pasa automáticamente a la función catch()si se ha definido. Es por eso que solo tenemos una cláusula catch()a pesar de que tenemos dos operaciones asincrónicas.

Confirmamos que nuestro programa produce el mismo resultado ejecutando:

node promiseMovies.js

En su carpeta ghibliMoviesverá el archivo que promiseMovies.csvcontiene:

Castle in the Sky, 1986
Grave of the Fireflies, 1988
My Neighbor Totoro, 1988
Kiki's Delivery Service, 1989
Only Yesterday, 1991
Porco Rosso, 1992
Pom Poko, 1994
Whisper of the Heart, 1995
Princess Mononoke, 1997
My Neighbors the Yamadas, 1999
Spirited Away, 2001
The Cat Returns, 2002
Howl's Moving Castle, 2004
Tales from Earthsea, 2006
Ponyo, 2008
Arrietty, 2010
From Up on Poppy Hill, 2011
The Wind Rises, 2013
The Tale of the Princess Kaguya, 2013
When Marnie Was There, 2014
promiseMovies.csv

Con promesas, podemos escribir código mucho más conciso que usar solo devoluciones de llamada. La cadena de devolución de llamada prometida es una opción más limpia que el anidamiento de devolución de llamada. Sin embargo, a medida que hacemos más llamadas asincrónicas, nuestra cadena de promesas se vuelve más larga y más difícil de cumplir.

La verbosidad de las devoluciones de llamada y las promesas proviene de la necesidad de crear funciones cuando tenemos el resultado de una actividad asincrónica. Una mejor experiencia sería esperar un resultado asincrónico y ponerlo en una variable fuera de la función. De esta forma, podemos usar los resultados en variables sin tener que crear una función. Podemos lograr esto con las palabras clave asyncy await.

Escribiendo JavaScript con async/await

Palabras clave async/ awaitproporcionan una sintaxis alternativa cuando se trabaja con promesas. En lugar de tener el resultado de una promesa disponible en el método then(), el resultado se devuelve como un valor como en cualquier otra función. Definimos una función con la palabra clave asyncpara decirle a JavaScript que es una función asincrónica que devuelve una promesa. Usamos la palabra clave awaitpara decirle a JavaScript que devuelva los resultados de la promesa en lugar de devolver la promesa en sí cuando se cumple.

En general, async/ se await  ve así:

async function() {
    await [Asynchronous Action]
}

Veamos cómo usar async/ awaitmejorar nuestro programa Studio Ghibli. Utilice su editor de texto para crear y abrir un nuevo archivo asyncAwaitMovies.js:

nano asyncAwaitMovies.js

En su archivo JavaScript recién abierto, comencemos por importar los mismos módulos que usamos en nuestro ejemplo de promesa:

const axios = require('axios');
const fs = require('fs').promises;
asyncAwaitMovies.js

Las importaciones son las mismas promiseMovies.jsque las promesas de por qué async/ awaituso.

Ahora usemos la palabra clave asyncpara crear una función con nuestro código asincrónico:

const axios = require('axios');
const fs = require('fs').promises;

async function saveMovies() {}
asyncAwaitMovies.js

Creemos una nueva función llamada saveMovies()e incluyamos asyncal principio de su definición. Esto es importante ya que solo podemos usar la palabra clave awaiten una función asincrónica.

Utilice la palabra clave awaitpara realizar una solicitud HTTP que obtenga la lista de películas de la API de Ghibli:

const axios = require('axios');
const fs = require('fs').promises;

async function saveMovies() {
    let response = await axios.get('https://ghibliapi.herokuapp.com/films');
    let movieList = '';
    response.data.forEach(movie => {
        movieList += `${movie['title']}, ${movie['release_date']}\n`;
    });
}
asyncAwaitMovies.js

En nuestra función saveMovies(), hacemos una solicitud HTTP axios.get()como antes. Esta vez no lo encadenamos con una función then(). En su lugar, agreguemos awaitantes de que se llame. Cuando JavaScript lo ve await, solo ejecutará el código restante de la función axios.get()después de la ejecución y establecerá la variable response. El otro código guarda los datos de la película para que podamos escribir en un archivo.

Escribamos los datos de la película en un archivo:

const axios = require('axios');
const fs = require('fs').promises;

async function saveMovies() {
    let response = await axios.get('https://ghibliapi.herokuapp.com/films');
    let movieList = '';
    response.data.forEach(movie => {
        movieList += `${movie['title']}, ${movie['release_date']}\n`;
    });
    await fs.writeFile('asyncAwaitMovies.csv', movieList);
}
asyncAwaitMovies.js

También usamos la palabra clave awaitcuando escribimos en el archivo con fs.writeFile().

Para completar esta función, necesitamos detectar los errores que nuestras promesas pueden generar. Hagamos esto encapsulando nuestro código en un bloque try/ catch:

const axios = require('axios');
const fs = require('fs').promises;

async function saveMovies() {
    try {
        let response = await axios.get('https://ghibliapi.herokuapp.com/films');
        let movieList = '';
        response.data.forEach(movie => {
            movieList += `${movie['title']}, ${movie['release_date']}\n`;
        });
        await fs.writeFile('asyncAwaitMovies.csv', movieList);
    } catch (error) {
        console.error(`Could not save the Ghibli movies to a file: ${error}`);
    }
}
asyncAwaitMovies.js

Dado que las promesas pueden fallar, incluimos nuestro código asincrónico con una cláusula try/ catch. Esto detectará cualquier error que se genere cuando la solicitud HTTP o las operaciones de escritura de archivos fallan.

Finalmente, llamamos a nuestra función asincrónica saveMovies()para ejecutar cuando ejecutamos el programa connode

const axios = require('axios');
const fs = require('fs').promises;

async function saveMovies() {
    try {
        let response = await axios.get('https://ghibliapi.herokuapp.com/films');
        let movieList = '';
        response.data.forEach(movie => {
            movieList += `${movie['title']}, ${movie['release_date']}\n`;
        });
        await fs.writeFile('asyncAwaitMovies.csv', movieList);
    } catch (error) {
        console.error(`Could not save the Ghibli movies to a file: ${error}`);
    }
}

saveMovies();
asyncAwaitMovies.js

A primera vista, parece un bloque típico de código JavaScript sincrónico. Tiene menos funciones pasadas, lo que parece un poco más ordenado. Estos pequeños cambios hacen que el código asincrónico con async/ awaitsea ​​más fácil de mantener.

Pruebe esta iteración de nuestro programa ingresándolo en su terminal:

node asyncAwaitMovies.js

ghibliMovies  Se creará un nuevo archivo en su carpeta asyncAwaitMovies.csvcon el siguiente contenido:

Castle in the Sky, 1986
Grave of the Fireflies, 1988
My Neighbor Totoro, 1988
Kiki's Delivery Service, 1989
Only Yesterday, 1991
Porco Rosso, 1992
Pom Poko, 1994
Whisper of the Heart, 1995
Princess Mononoke, 1997
My Neighbors the Yamadas, 1999
Spirited Away, 2001
The Cat Returns, 2002
Howl's Moving Castle, 2004
Tales from Earthsea, 2006
Ponyo, 2008
Arrietty, 2010
From Up on Poppy Hill, 2011
The Wind Rises, 2013
The Tale of the Princess Kaguya, 2013
When Marnie Was There, 2014
asyncAwaitMovies.csv

Ahora ha utilizado JavaScript async/ características awaitpara manejar código asincrónico.      

Conclusión

En este tutorial, aprendió cómo JavaScript maneja la ejecución de funciones y el manejo de operaciones asincrónicas con el bucle de eventos. Luego, escribió programas que crearon un archivo CSV después de realizar una solicitud HTTP para los datos de la película utilizando varias técnicas de programación asincrónica.

Support us with a

Successivamente, completa il checkout per l'accesso completo a Noviello.it.
Bentornato! Accesso eseguito correttamente.
Ti sei abbonato con successo a Noviello.it.
Successo! Il tuo account è completamente attivato, ora hai accesso a tutti i contenuti.
Operazione riuscita. Le tue informazioni di fatturazione sono state aggiornate.
La tua fatturazione non è stata aggiornata.