Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simpler solution for fetch-basic #16

Open
tkrotoff opened this issue Nov 2, 2020 · 1 comment
Open

Simpler solution for fetch-basic #16

tkrotoff opened this issue Nov 2, 2020 · 1 comment

Comments

@tkrotoff
Copy link

tkrotoff commented Nov 2, 2020

In your fetch-basic example you read the response then "pipe" it to a new response:

...
return new Response(
    new ReadableStream({
      start(controller) {
        const reader = response.body.getReader();

        read();
        function read() {
          reader.read().then(({done, value}) => {
            if (done) {
              controller.close();
              return; 
            }
            loaded += value.byteLength;
            progress({loaded, total})
            controller.enqueue(value);
            read();
          }).catch(error => {
            console.error(error);
            controller.error(error)                  
          })
        }
      }
    })
  );
})
.then(response => response.blob())
.then(data => {
  status('download completed')
  document.getElementById('img').src = URL.createObjectURL(data);
})
...

There is no need to perform this extra work:

const content = []; // <===
let bytesReceived = 0;

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  content.push(value); // <===
  bytesReceived += value.byteLength;
}

document.getElementById('img').src = URL.createObjectURL(new Blob(content));

Full example:

const progressIndicator = document.getElementById('progress');

const { headers, body } = await fetch(
  'https://fetch-progress.anthum.com/30kbps/images/sunrise-baseline.jpg'
);

const contentLength = headers.get('Content-Length');
if (contentLength === null) throw new Error('No Content-Length response header');
const totalBytes = parseInt(contentLength, 10);
progressIndicator.max = totalBytes;

if (body === null) throw new Error('No response body');
const reader = body.getReader();

const content = []; // <===
let bytesReceived = 0;

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  content.push(value); // <===
  bytesReceived += value.byteLength;

  progressIndicator.value = bytesReceived;
}

document.getElementById('img').src = URL.createObjectURL(new Blob(content));
<progress id="progress" value="0"></progress>
<img id="img" alt="download-progress-img" src="data:,">
@anthumchris
Copy link
Owner

@tkrotoff thanks for reaching out. I won't be able to look at this this week, but please ensure that browser compatibility isn't affected since the time this was originally released. If that's a non-issue, happy to revise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants