-
-
Notifications
You must be signed in to change notification settings - Fork 267
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: