jimmywarting / StreamSaver.js

StreamSaver writes stream to the filesystem directly asynchronous
https://jimmywarting.github.io/StreamSaver.js/example.html
MIT License
4.04k stars 418 forks source link

Download dialogue opens before completion #161

Closed allengordon011 closed 4 years ago

allengordon011 commented 4 years ago

This is my first time working with streams. I've been trying various configurations based on the examples here and elsewhere. My chunks come through in an object { chunk, done }, and require another call to the API for the next chunk. (note: it's coming through a Websocket, not fetch) I can't seem to quite nail down how to delay the download dialogue until I've received done: true from my API. Please help if you can.

Note: writer is created outside this function to avoid creating a new writer on every iteration. It looks like this:

const writableStream = streamSaver.createWriteStream(fileName, { size });
const writer = writableStream.getWriter();
let readableStream;
        if (response.chunk) {
          readableStream = new ReadableStream({
            start (ctrl) {
              const nextChunk = async () => await dispatch(getBackupDownload(stream, writer))
                .catch(e => dispatch(createNotification({ category: 'error', message: e.message }, 'Backup')));
              ctrl.enqueue(response.chunk);
              if (!response.done) {
                nextChunk();
              } else {
                console.log('close!');
                ctrl.close();
              }
            },
          });
        } else {
          console.log('NO CHUNK');
        }

        const reader = readableStream.getReader();
        const pump = () => reader.read()
          .then((res) => {
            console.log('pump', res);
            if (!res.done) {
              writer.write(res.value).then(pump);
            }
          });
        pump();
        if (response.done) {
          writer.close();
          resolve(response);
        }
allengordon011 commented 4 years ago

Solved. I was creating multiple ReadableStreams.