Páginas

lunes, 6 de enero de 2020

Ejemplo de llamada al api fetch síncrona


Objetivo

En este post se explica cómo se puede utilizar fetch para obtener un fichero json que está en la red y mostrarlo mediante un browser. Lo interesante es el ejemplo de cómo hay que codificar las funciones, para que el  orden en que se ejecutan las sentencias javascript sea el adecuado y de esta forma evitar asincronías no deseadas. Por ejemplo, ir a mostar un dato del que todavía no se dispone.

El API fetch es asíncrono, esto quiere decir que cuando se ejecuta, se lanza la petición del fichero json y la ejecución continúa sin esperar a que el fichero haya sido recuperado. Si esto no se tiene en cuenta, no tendremos garantía de obtener la respuesta adecuada, puesto que lo que queremos es mostrar dicho fichero en la pantalla y hasta que no tengamos el fichero completo no podremos presentarlo.

Punto de partida

En este ejemplo se usa el API REST  https://jsonplaceholder.typicode.com/ , es un  api suministrado de forma gratuita para poder realizar pruebas.
 
Para crear la infraestructura de este ejemplo, se inicia un proyecto node express (https://expressjs.com/en/starter/hello-world.html).  Este framework se usa para construir las bases de la aplicación, que arrancan un servidor que resuelve peticiones http por el puerto 3000.

Ejemplo

Se prepara la aplicación que una vez arrancada con el comando "node app.js". Esta aplicación como se se puede observar escucha en el puerto 3000

node app.js
Example app listening on port 3000!

Una vez arracada, abrir una ventana del browser y escribir http://localhost:3000/damepost
 
Siguiendo la estructura de un proyecto node express, para dar respuesta a esta petición hemos escrito un módulo app.js. Este módulo es el que arranca la aplicación y tiene codificada la ruta “/damepost”.  Ver a continuación app.get. Aquí es donde se indica lo que la aplicación tiene que hacer cuando se escribe la petición http http://localhost:3000/damepost

app.js

const express = require('express')
const app = express()
const port = 3000
const f = require('./functionsRefactored.js')

app.get('/damepost'async (reqres=> res.send(await f.hagoFetch())) 

app.listen(port, () => console.log(`Example app listening on port ${port}!`))

Cuando se realiza la petición http://localhost:3000/damepost, la aplicación llama a la función

 async (req, res) => res.send(await f.hagoFetch())

Esta arrow function llama a hagoFetch(). Esta función está exportada desde el módulo functionsRefactored.js que se muestra a continuación.

functionsRefactored.js

fetch = require('node-fetch');

async function hagoFetch() {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts/1')
    .catch(error =>{console.error(error)})
  const json = await response.json();
  return json
}

exports.hagoFetch=hagoFetch;


En hagoFecth se solicita el fichero json que devuelve todos los posts del usuario cuya identificación es 1. La solicitud se hace con await, es decir el control de ejecución para y espera hasta que response.joson() termina para continuar. 
 
Una vez que se dispone de response, se obtiene el fichero json con el método json(). Este método también se invoca de forma síncrona con await. Por lo tanto, hagoFetch() no retorna la constante json hasta que no contiene todos los datos.

Resumen

Convertir en síncrona la petición fetch, se ha conseguido mediante dos llamadas con await.

  1.  await fetch(….) no devuelve la constante response hasta que  fetch ha terminado.  
  2.  await response.json() no devuelve la constante json hasta que la función ha terminado.

Para poder hacer await dentro de la función  hagoFetch() se ha tenido que declarar como función async.
A su vez la llamada a la función hagoFetch en app.js se hace con await. Para poder hacer await la arrow function de app.get  para la ruta /damepost está declarada como async.

Espero que esto sea de utilidad para alguien por ahí que se esté pegando con fetch y la asincronía. Si tenéis alguna duda dejad un comentario.

No hay comentarios:

Publicar un comentario