A煤n no tienes acceso a esta clase

Crea una cuenta y contin煤a viendo este curso

Fetch - C贸mo cancelar peticiones

20/42
Recursos

La peticiones AJAX permitieron en su tiempo hacer peticiones as铆ncronas al servidor sin tener que detener la carga de la p谩gina. Hoy en d铆a se utiliza la funci贸n fetch para esto.

Con fetch tenemos algo llamado AbortController que nos permite enviar una se帽al a una petici贸n en plena ejecuci贸n para detenerla.

Aportes 91

Preguntas 12

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesi贸n.

Ey chicos me tome el tiempo para traerles las mejores notas del curso, denle una checada porfavor a mis notas, y si son de su agrado dejenme un like en github. Saludos 馃槃
Notas o https://github.com/JasanHdz/javascript-professional/tree/master/notes

Apuntes de la clase

Todos simulando una conexi贸n lenta mientras yo vivo en ella 馃槃 saludos de Venezuela

Dejo el c贸digo del inicio para el que lo necesite:

<html>
  <head>
    <title>Abort Fetch</title>
  </head>
  <body>
    <a href="/ejercicios/">Go back</a>
    <p><em>Abre la consola</em></p>

    <img 
        id="huge-image" 
        height="400"
    />
    <button id="load">Load HUGE Image</button>
    <button id="stop" disabled>Stop Fetching</button>
    
    <script>
        const url = 
        'https://images.pexels.com/photos/974470/nature-stars-milky-way-galaxy-974470.jpeg?q=100';
      const img = document.getElementById('huge-image');
      const loadButton = document.getElementById('load');
      const stopButton = document.getElementById('stop');


      function startLoading() {
        loadButton.disabled = true;
        loadButton.innerText = 'Loading...';
        stopButton.disabled = false;
      }
      function stopLoading() {
        loadButton.disabled = false;
        loadButton.innerText = 'Load HUGE Image';
        stopButton.disabled = true;
      }

      loadButton.onclick = async function() {
        startLoading();
        stopLoading();
      };

      stopButton.onclick = function() {
        stopLoading();
      };
    </script>
  </body>
</html>

El m茅todo fetch abrir谩 un canal de comunicaci贸n con un recurso externo (en red) devolviendo una promesa, por lo tanto se puede acceder a la respuesta mediante un then.

fetchResponsePromise = fetch(resource, init);

Como todas las promesas se puede acceder a la respuesta dentro de funciones async, mediante al el uso de la palabra reservada await y de esta manera utilizar de manera m谩s sencilla la respuesta.

fetch(myRequest).then(function(response) {
	// code
});

fetch historicamente proviene del XMLHttpReques (o XHR para los cuates) con un funcionamiento similar al JQUERY.ajax (Asyncronous JavaScript And XML) con un mejor manejo de los errores (ya que fetch s贸lo fallar谩 cuando hayan problemas de red, manejando los errores mediante Response.status, Response.statusText y Response.ok).
.
Una de las ventajas adicionales que se manejan con fetch vs XHR, es que fetch permite la cancelaci贸n de una se帽al (signal) mediante objetos de tipo AbortController.
.
Para conseguir la se帽al interrumpida se debe de configurar un objeto de tipo AbortController, mismo que tiene una objeto de tipo AbortSignal, que es el que especificar谩 si la se帽al se ha interrumpido o no (mediante AbortSignal.aborted)

let controller =  new AbortController()

En el objeto de configuraci贸n del await existe un atributo llamado signal que recibe una se帽al de tipo AbortSignal (para este caso se guard贸 en el controller).

const response = await fetch(url, {signal: controller.signal});

Para parar la se帽al, s贸lo debemos acceder al m茅todo abort() del AbortController que genera el AbortSignal

controller.abort();

No me hizo falta hacer ninguna modificaci贸n en el inspector de google鈥

blob es el binario de la petici贸n que estamos pidiendo.

const response = await fetch(url);
const blob = await response.blob();
  • Este binario no se puede pasar directamente a la imagen, hay que convertirlo a una url.
    鈥 El navegador trae una utilidad para realizar ese paso: URL.createObjectURL()
const imgUrl = URL.createObjectURL(blob);

鉃★笍Mas informaci贸n:
blob(): https://developer.mozilla.org/en-US/docs/Web/API/Body/blob
blob: https://developer.mozilla.org/es/docs/Web/API/Blob
URL.createObjectURL(): https://developer.mozilla.org/es/docs/Web/API/URL/createObjectURL

AbortController.abort ()

El m茅todo abort() de la la interfaz AbortController. Esta interfaz anula una solicitud DOM (por ejemplo, una solicitud Fetch) antes de que se haya completado. Esto puede abortar las solicitudes de recuperaci贸n, el consumo de cualquier respuesta Bodyy las transmisiones.

Sintaxis

controller.abort();

Ejemplos

En el siguiente fragmento, nuestro objetivo es descargar un video usando la API Fetch .

Primero creamos un controlador usando el AbortController()constructor, luego tomamos una referencia a su AbortSignalobjeto asociado usando la AbortController.signalpropiedad.

Cuando se inicia la solicitud de b煤squeda , pasamos el AbortSignalcomo una opci贸n dentro del objeto de opciones de la solicitud (ver m谩s {signal}abajo). Esto asocia la se帽al y el controlador con la solicitud de recuperaci贸n y nos permite abortarla llamando AbortController.abort(), como se ve a continuaci贸n en el segundo detector de eventos.

var controller = new AbortController();
var signal = controller.signal;

var downloadBtn = document.querySelector('.download');
var abortBtn = document.querySelector('.abort');

downloadBtn.addEventListener('click', fetchVideo);

abortBtn.addEventListener('click', function() {
  controller.abort();
  console.log('Download aborted');
});

function fetchVideo() {
  ...
  fetch(url, {signal}).then(function(response) {
    ...
  }).catch(function(e) {
    reports.textContent = 'Download error: ' + e.message;
  })
}

Nota : Cuando abort()se llama, la fetch()promesa se rechaza con un AbortError.

Puede encontrar un ejemplo de trabajo completo en GitHub: vea abort-api ( vea tambi茅n c贸mo se ejecuta en vivo ).

Recuerden deshabilitar el cache en esta practica 馃憖

si el usuario no esta bendecido con una internet r谩pida 馃ぃ

recuerden deshabilitar su cache en un checkbox que esta en network.
si necesitas una imagen mas pesada

img

Los BLOB (Binary Large Objects, objetos binarios grandes) son elementos utilizados en las bases de datos para almacenar datos de gran tama帽o que cambian de forma din谩mica. No todos los Sistemas Gestores de Bases de Datos son compatibles con los BLOB.

Generalmente, estos datos son im谩genes, archivos de sonido y otros objetos multimedia; a veces se almacenan como c贸digos de binarios BLOB.

驴Q煤e diferencia hay en usar addEventListener() y usar onclick?

Tuve que ver el video como 4 veces pero me sirvi贸, lo entend铆 al final

馃敡Les recomiendo que para el manejo de errores no usen console.log sino console.error

Soy nuevo en JS as铆 que entiendo poco de los botones y llamados pero el concepto es claro.

Que explicaciones tan malas por que abortan los temas tan rapido

No entiendo como es que la funcion stopButton.onclick puede acceder a controller.abort(), si controller = new AbortController fue definido en loadButton.onclick?

les dejo otro ejemplo del abort

ejemplo:

/***
 * Supongamos que tenemos una request y queremos cancelarla si la misma tarda mas mas de 2 segundos. 
**/

// aca tenemos el fetch comun y corriente
const url = "https://images.pexels.com/photos/974470/nature-stars-milky-way-galaxy-974470.jpeg?q=100";
let imgUrl

const respose = await fetch(url);
const blob = await respose.blob();
imgUrl = URL.createObjectURL(blob);
/**
 * Ahora para poder cancelar el fecth necesitamos usar el AbortController
**/
const url = "https://images.pexels.com/photos/974470/nature-stars-milky-way-galaxy-974470.jpeg?q=100";
let imgUrl

//1. instanciamos el controller 
const controller = new AbortController();

// 2. lo que vamos a hacer es un timmer, que si en 2 segundos no se resolvio la imgUrl cancelamos el fetch 

setTimeout(()=>{if(!imgUrl) controller.abort()},2000)

//3. ahora debemos pasarle al fetch el method signal como option
const respose = await fetch(url, {signal: controller.signal});
const blob = await respose.blob();
imgUrl = URL.createObjectURL(blob);

Que interesante!!

Bastante interesante !

yo creia que sabia algo de js, gracias por el contenido

Mi primer encuentro con fetch no fue tan grato, no lograba obtener la respuesta creo que por problemas de cors.

Decid铆 implementar axios y con mi compa帽ero de trabajo nos solucion贸 toda la parte de comunicaci贸n con el servidor.

Alguien esta trabajando en proyectos reales con fetch o prefieren una librer铆a como axios? Yo soy de esas personas que prefieren usar lo nativo y no sobrecargar los proyectos de librer铆as, pero por encima esta siempre la practicidad.

BLOB son las siglas de Binary Large Object

Lo mejor es que no tuve que simular un internet lento, ya lo tengo de 1mb 馃槈

URL.createObjectUrl([blob]) --> This help us to create an object based on a blob format. (images, json, etc) --> All the browsers have this feature to convert and use this.

Gracias, no conoc铆a este m茅todo para cancelar fetch, as铆 que lo que hac铆a era cancelar 鈥淧romise鈥 utilizando otro promise para los resultados. No era muy limpio, debido a que la manera de cancelar el 鈥淧romise鈥 era hacer 鈥渞eject鈥 de la 鈥淧romise鈥 que encapsulaba la 鈥淧romise鈥 del fetch.

Aqu铆 m谩s referencias de como hacer 鈥淧romise鈥 que se puedan cancelar: https://medium.com/@masnun/creating-cancellable-promises-33bf4b9da39c#:~:text=There are reliable open source solutions for cancellable promises.&text=A function%2C when called%2C would,return it to the caller.

  1. Para mostrar errores en consola cuando usamos la estructura try/catch podemos usar
console.error()
  1. Blob = Binary Large OBject

Mi Bro (Jasanhdz) genial tu aporte, enserio muchas gracias por tomarte el tiempo y la dedicaci贸n te quedo genial lo sugerir茅 para otros q conozco que les gusta el lenguaje.

Creo que algo que es necesario aclarar que el profesor no explic贸 es que Fetch puede recibir opcionalmente un objeto de configuraci贸n en este caso all铆 es donde pasamos la se帽al del controller para luego usar el controller.abort(). 馃槃

Casi que no lo logro recrear, al final me sali贸 pero es muy buena idea tener la opcion de cancelar un fetch.

No se si solo sea yo, pero me gustar铆a que subieran el archivo en que se trabaja (abort-fetch.html) como se empieza en la clase, no cuando lo modifican. Ser铆a bueno para tener listo el punto de partida.

  • Los Blobs representan datos que no necesariamente se encuentran en un formato nativo de JavaScript. 鈥 por ejemplo pasa este dato de imagen lo pasa a binario y asi empezamos a jugar con el en JS.

  • Con URL.createObjectURL(blob) obenemos una url la cual el DOM entiende (img.src) pas谩ndole por par谩metro un binario en este caso el blob.

Con fetch tenemos algo llamado AbortController que nos permite enviar una se帽al a una petici贸n en plena ejecuci贸n para detenerla.

Interesante鈥 muchas gracias!!

Profesor: "Si el usuario no est谩 bendecido con una conexi贸n de internet r谩pida esto puede ser horrible"
Yo: 馃槱

repet铆 la clase como 3 o mas veces
pero creo que lo entend铆

Fetch tenia un problema antes, al salir una petici贸n hacia una API era imposible cancelar dicha petici贸n, por lo que si haciamos una petici贸n que no queriamos y queriamos seguir navegando normalmente habr铆a que esperar hasta que dicha petici贸n se concluyera para luego seguir navegando. Para solucionar eso lleg贸 AbortController, al realizar la petici贸n con fetch as铆ncronamente, y al traer los datos de la url, existe un m茅todo llamado 鈥渂lob()鈥 que convierte el response del fetch en c贸digo binario, pero en este caso estamos usando una imagen como response, por lo que no podemos pasarle a la funci贸n un c贸digo binario sino convertir ese codigo a URL. Para lograr eso, todos los navegadores tienen incorporado un m茅todo llamado URL.createObjectURL() y lo que hay que pasarle es el c贸digo binario o el blob que hicimos del fetch a la url de la imagen, y el navegador se encargar谩 de convertir el blob o c贸digo binario a URL, y es esa URL la que utilizaremos para asignarle a la imagen
.
Luego por si la imagen tarde mucho implementaremos lo que viene siendo el tema de clase, cancelar dicha petici贸n mientras esta tarde mucho, para eso pasaremos un objeto de configuraci贸n en el fetch a la url, y pasaremos un signal, de donde vendr谩 dicho signal? Aqu铆 es donde entra AbortController, que nos dar谩 los controles para poder cancelar una petici贸n. AbortController es una clase, por lo que hay que instanciarla. AbortController tiene se帽ales, que es la que nuestro atributo del objeto de configuraci贸n signal necesita. Luego cuando querramos detener la ejecuci贸n realmente, con el boton designado para eso, usamos el m茅todo abort de AbortController. Cabe destacar que nuestro AbortController debe tener un scope global para un mejor uso, ya que cuando lo instanciamos estamos usando en la funci贸n de cargar la imagen, por lo que esa instancia debe tener scope global para poder acceder tambi茅n al bot贸n disparador del cancelamiento de la petici贸n, y para realizar el cancelador simplemente tenemos que ejecutar el m茅todo abort() del AbortController

A mi incluso con Slow 3G me carga muy r谩pido

Gente, me apoye en este video para reforzar https://www.youtube.com/watch?v=cjrt3NilcNw

muy bueno, entiendo que con fetch y blob y URL.createObjectUrl() podr铆as consultar alg煤n recurso que necesite autorizaci贸n (ejemplo una imagen privada o un v铆deo ) y si la auth es correcta servirlo en el navegador. Supongo que Platzi y los videos deber铆a funci贸n similar, tengo que tener sesi贸n iniciada y permisos para acceder al recurso del video

Introduccion de la clase
La peticiones AJAX permitieron en su tiempo hacer peticiones as铆ncronas al servidor sin tener que detener la carga de la p谩gina.
Esto llego con un m茅todo llamado XMLhttprequest, usarlo era laborioso, mucho proceso para hacer una petici贸n.
Ahora se utiliza la funci贸n fetch para esto de forma mas simple vecha las promesas.
El problema era que una vez que una petici贸n salia no hab铆a forma de detenerla. Esto es importante en SPA donde el usuario puede salir de una p谩gina y as铆 quedarse una llamada que estaba ocurriendo. Ser铆a preferible detener la llamada asi ahorrar una bytes y mejorar el rendimiento de nuestra app.
AbortController que nos permite enviar una se帽al a una petici贸n en plena ejecuci贸n para detenerla.

Bastante 煤til la clase

Esto se parece mucho a lo que aprend铆 en kotlin-android, se me har谩 m谩s sencillo el aprendizaje 馃槃

Tuve problemas con el Scope de la variable controller, declarandola con let el stopButton no tenia acceso a ella, asi que la declare una sola vez con var y funcion贸

Hola, les dejo la documentaci贸n de esta API del DOM. https://developer.mozilla.org/en-US/docs/Web/API/AbortController.

No hay mucho que ver, ya solo tiene el m茅todo abort que vimos en la clase. Pero ah铆 se encuentra un ejemplo, pienso que valdr铆a la pena hecharle un ojo.

Si observan que en la parte de 鈥淭ime鈥 y 鈥淲aterfall鈥 en Sources aparece como Pending y no hay actividad, o si les aparece en la consola que tienen un error de CORS (temas de seguridad), agreguen lo siguiente justo al lado de controller.signal poniendo una coma:

mode: "no-cors"

De esta manera, el tiempo y la barra se ir谩n actualizando en tiempo real.


Atenci贸n:

Prohibido agregar esto en etapa de Producci贸n. S贸lo se usa por motivos de visualizaci贸n en tiempo real por bloqueo de CORS.

Cancelar peticiones

Fetch aprovecha las promesas para pder realizar peticiones. El Problema es que fetch no podia cancelar las peticiones hasta ahora. En ocaciones es preferible detener una llamada para poder ahorrarnos espacio y hacer mas eficiente la aplicacion. Aqui llega AbortController. Permite dar una senal a una peticion FETCH para que se detenga.

Para esto en el FETCH neceistamos darle un objeto de configuracion donde le demos un URl ppondremos unos {} con un objeto de configuracion llamado Signal y esta vendra de un AbortController. Que nos dara los controles para detener la ejecucion. Esto se veria asi:

let controller = new AbortControler();
const response = await fetch(url, {signal: controller:signal});

Ahora si queremos detener, neceistamos llamar a nuestro:

controller.abort();

Fetch es un m茅todo de traer informaci贸n desde un API por medio de promesas. Antiguamente no hab铆a forma de detener una promesa que ya fue enviada hasta que apareci贸 Abort Controller.

Abort Controller permite enviar una se帽al a una petici贸n fetch para que se detenga.


Para crear una url de un blob:

const imgUrl = URL.createObjectURL(blob)

Para detener la petici贸n

const controller = new AbortController();

const response = await fetch(url, {signal: controller.signal});
const blob = await response.blob();
const imgUrl = URL.createObjectURL(blob);
img.src = imgUrl

// se le debe pasar el signal de controller al fetch
// para detener la petici贸n:
controller.abort()

Cuando se cancele el fetch lanzar谩 un error por lo que hay que manejarlo.

URL.createObjectUrl([blob])

  • This help us to create an object based on a blob format. (images, json, etc)
  • All the browsers have this feature to convert and use this.

interesante, siempre me pregunt茅 como cancelar una petici贸n echa usando fetch.

el primer encuentro con fetch fue dificil, pero cuando entiendes la sintaxis el uso que puedes hacer es muy bueno (Y)

Bunea expliacion de como cancelar una peticion o Fetch

Por si les interesa mi blogpost sobre fetch, axios y otras cosillas
fetch_axios_etc

Esto puede ser muy 煤til para la carga de las Single Page Applications 馃槷

Bendecido y afortunado por el internet

Los que no tenemos una conexi贸n bende鈥
LOADING....

La peticiones AJAX permitieron en su tiempo hacer peticiones as铆ncronas al servidor sin tener que detener la carga de la p谩gina. Hoy en d铆a se utiliza la funci贸n fetch para esto.

Alguien sabe porque no sirve en Opera? pero en Chrome si?

excelente clase cada momento aprendemos mucho m谩s

Excelente clase, esto me parece genial y muy util para proyectos que manejan peticiones con consultas muy grandes al server!

驴Alguien se da idea de como hacer para poder volver a cargar la imagen, una vez que abortamos el fetch? Estuve busc谩ndole la vuelta pero no la encuentro. Cuando quiero volver a fetchear me tira 鈥淭he User Aborted a Request鈥 en consola.

Puse el throttling en slow 3G y me cargo en el mismo tiempo 馃槱馃槱

馃槃

Alguien sabe donde hay una buena documentaci贸n de fetch? Solo encuentro la de Mozilla y no me queda del todo claro.

No entiendo porque al ultimo del onclick de loadbutton se llama la funcion de stopLoading();

馃憤 Super. Gracias

Genial, super genial

No se si alguno tuvo el mismo problema que yo y es que no me permite cancelar la petici贸n ya que el bot贸n se iba inmediatamente para ello encontr茅 un soluci贸n muy breve y la comparto por si a alguien le sirve 馃槃.

Fue tan sencillo como usar la propiedad FileReader que b谩sicamente lo que hace es que permite leer un fichero en este caso en formato .blob.
Para ello se cre贸 el reader, a dicha instancia del FileReader con el m茅todo readAsDataURL se le pasa como par谩metro el fichero y se espera con await para manejarlo como un evento as铆ncrono.
Hecho esto gracias al m茅todo onloadend que me permite pasarle una funci贸n que se va a ejecutar cuando termine la lectura del fichero ya puedo manejar ah铆 mi evento.

Excelente herramienta.

Muy util

Que clase tan buena, me encanto

Excelente me parece una funcionalidad genial

Hola a todos, disculpen, alguien me puede decir d贸nde sale la opci贸n de network con toda la informaci贸n que muestra el profe, en el navegador de Mozilla?

La API fetch proporciona una interfaz JS para acceder y manipular partes de las solicitudes HTTP, como solicitudes y respuestas. Este m茅todo fetch() tambi茅n proporciona una l贸gica y f谩cil manera de obtener recursos de forma as铆ncrona a trav茅s de las redes.(source)

Gracias que buena explicaciones

Fetch

Las peticionas AJAX, fueron todo un hito en la web, puer nos permitieron cargar infromaci贸n sin tener que recargar toda la p谩gina. Para esto, se utiliza el m茅todo XMLHttpRequest, pero su implementaci贸n llega a ser un poco compleja en ciertos casos. Es por esto que llega la funci贸n fetch para simplificar nuestros requests, con la ventaja de que aprovecha las promesas. La 煤nica desventaja era que no hab铆a modo de cancelar una petici贸n, lo cu谩l es muy importante en Single Page Applications, en donde puede que una respuesta as铆ncrona rompa flujos o sobrecargue datos innecesarios. Para ello lleg贸 abortController. Consideremos este ejemplo, en el que queremos cargar una imagen muy pesada.

Consideremos las siguientes funciones as铆ncronas, que est谩n preparadas para hacer el request de una imagen y asignarla a un elemento img de nuestro HTML, con la opci贸n de abortar dicha petici贸n:

startButton.onclick = async function() {
  startLoading()
  // intanciamos AbortController
  controller = new AbortController()
    try {
      // pasamos la se帽al del controller
    const response = await fetch(url, {signal: controller.signal})
    // extraemos el archivo binario de la respuesta
    const blob = await response.blob()
    // generamos una url para colocar al elemento img
    const imgUrl = URL.createObjectURL(blob)
    img.src = imgUrl
  } catch(error) {
    console.error(error.message)
  }
  stopLoading()
}
stopButton.onclick = async function() {
  // abortamos el fetch
  controller.abort()
  stopLoading()
}

Muy bueno!

Este video me oriento para entender archivos blob y su funcionamiento. Lo recomiendo.
https://www.youtube.com/watch?v=9Ih7ZIF5lpE&t=185s

aqui una imagen

Si quieren profundizar en el tema de las DevTools ya hay un curso de Platzi sobre eso: Curso de Debugging con Chrome DevTools

muy buen ejemplo.

Uhhh es bueno saber que se pueden cancelar, podr铆a ser bueno usar esto en los hooks de destroy de componentes de Vue ^^

Las promesas ya tienen un try catch invisible, no es necesario usar la sentencia en expl铆cito.
Otro dato, cualquier funci贸n as铆ncrona es una promesa.

El m茅todo fetch abrir谩 un canal de comunicaci贸n con un recurso externo (en red) devolviendo una promesa, por lo tanto se puede acceder a la respuesta mediante un then

El m茅todo fetch abrir谩 un canal de comunicaci贸n con un recurso externo (en red) devolviendo una promesa, por lo tanto se puede acceder a la respuesta mediante un then. Como todas las promesas se puede acceder a la respuesta dentro de funciones async, mediante al el uso de la palabra reservada await y de esta manera utilizar de manera m谩s sencilla la respuesta. El fetch historicamente proviene del XMLHttpReques con un funcionamiento similar al JQUERY.ajax con un mejor manejo de los errores.

El m茅todo fetch abrir谩 un canal de comunicaci贸n con un recurso externo (en red) devolviendo una promesa, por lo tanto se puede acceder a la respuesta mediante un then. Como todas las promesas se puede acceder a la respuesta dentro de funciones async, mediante al el uso de la palabra reservada await y de esta manera utilizar de manera m谩s sencilla la respuesta. fetch historicamente proviene del XMLHttpReques (o XHR para los cuates) con un funcionamiento similar al JQUERY.ajax (Asyncronous JavaScript And XML) con un mejor manejo de los errores (ya que fetch s贸lo fallar谩 cuando hayan problemas de red, manejando los errores mediante Response.status, Response.statusText y Response.ok).

Muy buena explicaci贸n