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
Add iterator(options) and return [Symbol.asyncIterator] #477
Comments
admittedly, you could probably do this without the change: async function main(){
let store = encode(leveldown('/path/to/db')))
let db = levelup(store);
let search = new LevelIterator(store, { keys: true, values: true, leq: "bar", limit: 10 }); |
Would it be possible/feasible to implement something on top of a async function main(){
const db = levelup(encode(leveldown()))
await db.put("foo", "hello")
await db.put("bar", "world")
const search = new ReadableStreamIterator(db.createReadStream({ leq: "bar", limit: 10 }))
for (let data of search) {
let key = data.key
let value = data.value
}
} This goes against your suggestion but also makes it more generic if it can operate on top of any |
See also: support of @mcollina @calvinmetcalf any thoughts? Until |
You can convert a stream to an asyncIterator, but you potentially have to buffer the stream if it produces faster than the consumer and its in push-mode. I don't like this solution, because the stream is redundent to using the underlying iterator directly and exposing it via Problem with In the mean time. I'm just writing a plugin to augment the levelup prototype and give you direct access the iterator, via asyncIterator. Those that want it can just import and use it. Then at a later stage it can be merged into levelup. I can update the levelup typings to allow merging definitions with third-party plugins to levelup, so the |
We can dream :)
👍 Instead of And instead of key-value objects, yield arrays, e.g.: const db = levelup(leveldown('./db'))
for await (let [key, value] of db.iterator()) {
console.log(key, value);
} Just spitballing, say we add const db = levelup(leveldown('./db'))
const iter = db.iterator()
for await (let [key, value] of iter) {
if (key == 'something to skip') {
iter.seek('yonder')
}
} |
Yes, ultimately you'd want this in the abstract iterator. But, again, I wouldn't recommend you do this yet. Sounds good, I'll change what I've got and get some tests going. |
@vweevers I've never seen the |
It is also available in node 7+ with the |
@ralphtheninja a contrived example: 'use strict'
// Run with: node --harmony-async-iteration example.js
async function example() {
for await(let [key, value] of new AbstractIterator()) {
console.log('%s: %s', key, value)
}
console.log('done!')
}
class AbstractIterator {
[Symbol.asyncIterator]() {
const pairs = [
['key1', 'foo'],
['key2', 'bar']
]
return {
next() {
return new Promise((resolve, reject) => {
setTimeout(() => {
const kv = pairs.shift()
resolve({ value: kv, done: !kv })
}, 500)
})
}
}
}
}
example() |
Upvoted! 😉 |
@vweevers What about the syntax for the class AbstractIterator {
[Symbol.asyncIterator]() { // <-- this one!
return {
next() {
// ..
}
}
}
} |
http://2ality.com/2015/02/es6-classes-final.html#computed-method-names. Sans classes you'd write: AbstractIterator.prototype[Symbol.asyncIterator] = function() {
return //..
} |
Proof of concept works nicely and the type merging works to. Bit more refactoring of levelup's typings and a new RC and I'll publish the plugin edit: I've uploaded the proof of concept: https://github.com/MeirionHughes/levelup-async-iterator and will publish when #481 is pulled |
@vweevers one hickup with let db = levelup(encode(leveldown('./db')));
async function main() {
await db.put("a", "John");
await db.put("b", "James");
await db.put("c", "Janet");
await db.put("d", "Joseph");
let iter = db.iterator();
for await (let [key, value] of iter) {
if(key === "a"){
iter.seek("c");
}
console.log(key, value);
}
} is that It'll work if you do it manually though: output: D:\Code\levelup-async-iterator>ts-node example
a John
c Janet
d Joseph |
Oh yes, it was just an illustration; |
Too much awesome stuff! |
Looks like async iteration is going stable - it is shipped in V8 - so hopefully we'll see it without flags in node 9 |
there is a good chance streams will support async iteration so that's probably a good direction to go in |
+1 |
Breaking this down:
|
I'd like to propose adding a method to
levelup
that would allow direct iteration of the underlyingstore.iterator
. This would negate the need for consumers to convert theReadStream
to an Iterable.from a usage perspective, something along the lines of:
not a huge change to implement this:
where
LevelAsyncIterator
can be the stream iterator butchered to remove the Stream aspects and simply implement[Symbol.asyncIterator]
instead - along with ability to end (clean) the underlyingstore.iterator
If people are happy with this proposal I can make the PRs and a newlevel-iterator
repo, based offlevel-stream-iterator
?I'll do it as a plugin to levelup due to
Symbol.asyncIterator
being still stage-3.The text was updated successfully, but these errors were encountered: