-
Notifications
You must be signed in to change notification settings - Fork 30
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
Cannot abort a stream that already has a writer
#92
Comments
You must not use If you acquired a writer (by calling To abort a const writableStream = createWritableStreamSomehow();
const writer = writableStream.getWriter();
// stream is now locked
writer.write("hello");
writer.write("world");
writer.abort(); or const writableStream = createWritableStreamSomehow();
// note: no getWriter(), so stream is unlocked
writableStream.abort(); Remember that you can use const writableStream = createWritableStreamSomehow();
const writer = writableStream.getWriter();
writer.write("hello");
writer.releaseLock();
// stream is now unlocked again
writableStream.abort(); |
Maybe, but it seems not possible when writing a library. // lib
export const createStream = () => {
const stream = new WritableStream({
// ...
})
on('abort', () => {
// we need to abort `stream` here and notify `writer` through error
stream.abort()
emit('aborted')
})
return stream
}
// user codes
import { createStream } from 'lib'
export const download = () => {
const writer = createStream().getWriter()
try {
await writer.write(xxx)
} catch(err) {
if (!err) {
// aborted
}
}
} |
It seems like you want to error the stream instead. Try this: export const createStream = () => {
let controller;
const stream = new WritableStream({
start(c) {
controller = c
},
// ...
})
on('abort', () => {
controller.error(new DOMException('Aborted', 'AbortError')) // or some other error
emit('aborted')
})
return stream
} If you want to do some logic when the user aborts the const stream = new WritableStream({
start(c) {
controller = c
},
abort(reason) {
// stop the download somehow
}
// ...
}) |
Thanks for your reply first.
I tried, but I don't know why when I add logic like
The user may abort by canceling downloading, so we need to notify the user's See https://github.com/jimmywarting/StreamSaver.js/blob/master/sw.js#L67 |
That doesn't make any sense. 😕 It doesn't sound like a problem with the polyfill, but rather with your code. I suggest you debug it and step through those lines of code to see what's going wrong.
No, the I don't know what your code looks like, but most of this
I don't understand why your code would even have a reader and a writer at the same time? 😕 |
Sorry, a typo, I mean
The first What we want is to cancel the export const pipeStream = async <T = unknown>(
reader: ReadableStreamDefaultReader<T>,
writer: WritableStreamDefaultWriter<T>,
signal?: AbortSignal,
) => {
let chunkResult: ReadableStreamDefaultReadResult<T>
let aborted: boolean | undefined
while (!signal?.aborted && !(chunkResult = await reader.read()).done) {
try {
await writer.write(chunkResult.value)
} catch (err) {
if (signal?.aborted) {
break
}
// we need some way to get notified when user aborts download
if (!err) {
aborted = true
break
}
throw err
}
}
if (signal?.aborted || aborted) {
await Promise.all([reader.cancel(), writer.abort()])
throw new DOMException('aborted', 'AbortError')
}
return writer.close()
}
const download = (readStream: ReadableStream<T>, fileName: string, signal?: AbortSignal) => {
const writeStream = streamSaver.createWriteStream(fileName)
pipeStream(readStream.getReader(), writeStream.getWriter(), signal)
} |
So basically you've built your own version of
This polyfill does implement these requirements, see the source. May I suggest a different approach? Instead of building a separate version of EDIT: Forget to mention, it's published as |
Thanks, will give it a try! |
@JounQin, curious to see if you are able to solve this. I'm also trying to support user download cancellation in my app with streamsaver. |
Hi, thanks for this great polyfill first.
I want to close the
WritableStream
when the user cancels the download process, but it throws as title, is there any solution?I'm using the hacky way currently.
The text was updated successfully, but these errors were encountered: