Is there an idiomatic/clean way to check a condition after each await in an async function, then return/throw conditionally?
For example, if we have a simple async function to upload a file to a websocket:
// readFileChunks is an async generator that returns 4KB of the file in every yield
async function upload(input) {
for(const file of input.files) {
const ws = await openUploadWebsocket(file.name)
for await(const chunk of readFileChunks(file, 4096)) {
await ws.write(chunk)
}
await ws.close()
}
}
input.onchange = upload
If we want to cancel this operation when user has reselected the files, we probably want to stop the previous run:
let previousLock = {stopped: false}
async function upload(input) {
previousLock.stopped = true
const lock = {stopped: false}
previousLock = lock
for(const file of input.files) {
const ws = await openUploadWebsocket(file.name)
try {
if(lock.stopped) return
for await(const chunk of readFileChunks(file, 4096)) {
if(lock.stopped) return
await ws.write(chunk)
if(lock.stopped) return
}
} finally {
await ws.close()
}
alert("Finished uploading")
}
}
input.onchange = upload
Now there is a lot of boilerplate because we have to check this condition after different await statements. Is there a better way to write this?