Security News
CISA Brings KEV Data to GitHub
CISA's KEV data is now on GitHub, offering easier access, API integration, commit history tracking, and automated updates for security teams and researchers.
abortable-generator
Advanced tools
Abortable AsyncGenerators using AbortControllers
npm i --save node-module-template
// esm
import abortable from 'abortable-generator`
// commonjs
const abortable = require('abortable-generator').default
There is a problem with AsyncGenerators where unsettled Promises can prevent them from finishing (and sometimes lead to memory leaks 😱)
async function* getItems() {
try {
yield new Promise((resolve) => {})
} finally {
// this never happens
}
}
const items = getItems()
setTimeout(() => {
// some time later
items.return()
}, 100)
for await (let item of items) {
// this never happens
}
Here's an example of how to abort "stuck" AsyncGenerators using abortable-generator
import abortable from 'abortable-generators'
// wrap your AsyncGenerators with `abortable` and use `raceAbort` inside
const getItems = abortable(async function* (raceAbort) {
yield raceAbort(new Promise((resolve) => {}))
})
const items = getItems()
setTimeout(() => {
// some time later
// return will trigger an abort
items.return()
}, 100)
for await (let item of items) {
// generator didn't yield anything
}
Here's an example of how to abort "stuck" AsyncGenerators using abortable-generator
import abortable from 'abortable-generators'
// wrap your AsyncGenerators with `abortable` and use `raceAbort` inside
const getItems = abortable(async function* (raceAbort) {
try {
yield raceAbort(new Promise((resolve) => {}))
} catch (err) {
if (err.name === 'AbortError') {
// return will throw an AbortError, but it will be ignored even if rethrown here
return
}
throw err
} finally {
// done
}
})
const items = getItems()
setTimeout(() => {
// some time later
// return will throw an AbortError into the generator
items.return()
}, 100)
for await (let item of items) {
// generator didn't yield anything
}
Here's an example of how to throw an error into a "stuck" AsyncGenerators using abortable-generator
import abortable from 'abortable-generators'
// wrap your AsyncGenerators with `abortable` and use `raceAbort` inside
const getItems = abortable(async function* (raceAbort) {
try {
yield raceAbort(new Promise((resolve) => {}))
} catch (err) {
// [Error: boom]
throw err
} finally {
// done
}
})
const items = getItems()
setTimeout(() => {
// some time later
// return will throw this error into the generator
const err = new Error('boom')
items.throw(err)
}, 100)
for await (let item of items) {
// generator didn't yield anything
}
Here's an example of how to abort "stuck" AsyncGenerators using abortable-generator
import abortable from 'abortable-generators'
const controller = new AbortController()
const signal = controller.signal
// wrap your AsyncGenerators with `abortable` and use `raceAbort` inside
const getItems = abortable(async function* (raceAbort) {
try {
yield raceAbort(new Promise((resolve) => {}))
} catch (err) {
if (err.name === 'AbortError') {
// abort will throw an AbortError, but it will be ignored even if rethrown here
return
}
throw err
} finally {
// done
}
})
// abort-signal can also be used to abort abortable generators
const items = getItems(signal)
setTimeout(() => {
// some time later
controller.abort()
}, 100)
for await (let item of items) {
//
}
Here's an example of how to abort AsyncGenerators that contain cancellable Promises (supporting AbortSignal)
import abortable from 'abortable-generators'
const getItems = abortable(async function* (raceAbort) {
try {
yield raceAbort((signal) => fetch('https://codeshare.io', { signal }))
} catch (err) {
if (err.name === 'AbortError') {
// cancelled fetch will throw an AbortError, but it will be ignored even if rethrown here
return
}
throw err
} finally {
// done
}
})
const items = getItems()
setTimeout(() => {
// some time later
items.return()
}, 100)
for await (let item of items) {
//
}
Here's an example of how to abort AsyncGenerators that contain cancellable Promises (supporting AbortSignal)
import abortable from 'abortable-generators'
const controller = new AbortController()
const signal = controller.signal
const getMoreItems = abortable(async function* (raceAbort) {
try {
await raceAbort(timeoutPromise(100))
yield raceAbort((signal) => fetch('https://codeshare.io', { signal }))
} catch (err) {
if (err.name === 'AbortError') {
// aborted promises will throw an AbortError, but it will be ignored even if rethrown here
return
}
throw err
} finally {
// done
}
})
const getItems = abortable(async function* (raceAbort) {
let moreItems
try {
moreItems = await raceAbort(signal => getMoreItems(signal))
for await (let item in moreItems) {
yield item
}
await raceAbort(timeoutPromise(100))
yield raceAbort((signal) => fetch('https://codeshare.io', { signal }))
} catch (err) {
if (err.name === 'AbortError') {
// aborted promises will throw an AbortError, but it will be ignored even if rethrown here
return
}
// if you want to throw an error into a child generator you'll need to call throw manually
// if (err instanceof FooError) await moreItems.throw(err)
throw err
} finally {
// done
await moreItems?.return()
}
})
// this signal can also be used to abort the generator!
const items = getItems(signal)
setTimeout(() => {
// some time later
items.return()
}, 100)
for await (let item of items) {
//
}
MIT
FAQs
Description
The npm package abortable-generator receives a total of 28 weekly downloads. As such, abortable-generator popularity was classified as not popular.
We found that abortable-generator demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISA's KEV data is now on GitHub, offering easier access, API integration, commit history tracking, and automated updates for security teams and researchers.
Security News
Opengrep forks Semgrep to preserve open source SAST in response to controversial licensing changes.
Security News
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.