Modern Asynchronous JavaScript: displaying images as they're loaded (page 50)

In Aborting Multiple Fetch Requests with One Signal section, the code in abort/abort_ex09.js doesn’t show the downloaded images until Promise.all fulfills, which means you need to wait for all the image downloads before seeing them. Also, if you cancel after some downloads have finished, you won’t see those images.

I suggest a small change to make it display the images as the corresponding promise fulfills:

33c33,38
<   const tasks = urls.map(url => fetch(url, {signal: controller.signal}));
---
>   const tasks = urls.map(url => fetch(url, {signal: controller.signal}).then(async (r) => {
>     const img = document.createElement('img');
>     const blob = await r.blob();
>     img.src = URL.createObjectURL(blob);
>     gallery.appendChild(img);
>   }));
36,43c41,43
<     const response = await Promise.all(tasks);
<     response.forEach(async (r) => {
<       const img = document.createElement('img');
<       const blob = await r.blob();
<       img.src = URL.createObjectURL(blob);
<       gallery.appendChild(img);
<     });
<     result.textContent = '';
---
>     Promise.all(tasks).then(() => {
>       result.textContent = '';
>     });

Hi Guilherme,

That’s a really good catch! Thanks! I’ll make sure to update the code example asap.

But your code looks a little weird with duplicated document.createElement(), etc. Did you mean something like this?

  const tasks = urls.map(url =>
  	fetch(url, {
  		signal: controller.signal
  	})
  	.then(async (r) => {
  		const img = document.createElement('img');
  		const blob = await r.blob();
  		img.src = URL.createObjectURL(blob);
  		gallery.appendChild(img);
  	})
  );
  
  try {
    const response = await Promise.all(tasks);
    result.textContent = '';
  } catch (err) {
    if (err.name === 'AbortError') {
      result.textContent = 'Request successfully canceled';
    } else {
      result.textContent = 'An error occurred!'
      console.error(err);
    }
  }

Hello Faraz. That’s because I posted the diff output, indicating which lines were removed with “<”, and which ones were added with “>”. The result should be like this:

  const tasks = urls.map(url => fetch(url, {signal: controller.signal}).then(async (r) => {
    const img = document.createElement('img');
    const blob = await r.blob();
    img.src = URL.createObjectURL(blob);
    gallery.appendChild(img);
  }));

  try {
    Promise.all(tasks).then(() => {
      result.textContent = '';
    });
  } catch (err) {
    if (err.name === 'AbortError') {
      result.textContent = 'Request successfully canceled';
    } else {
      result.textContent = 'An error occurred!'
      console.error(err);
    }
  }

Oh, my bad! :grinning: Thanks for clarifying that. We’re updating the code in the next version of the book.