Level / abstract-leveldown

An abstract prototype matching the leveldown API.
MIT License
146 stars 53 forks source link

Proof of concept: asyncIterator #338

Closed vweevers closed 3 years ago

vweevers commented 5 years ago

Do not merge. Ignore failing tests.

This is to find out what we need to support Symbol.asyncIterator in userland (we cannot do it here because we need async generators to properly handle ending on errors, and async generators are only available in Node 10+ and Chrome).

The answer is that we need to add Promise support to iterator.next() and .end(). We can do that in the same way as levelup: if you don't provide a callback argument, you get back a Promise.

This means there will be three ways to iterate:

  1. callbacks
  2. async/await (a bit awkward)
const it = db.iterator()
const kv = await it.next()

if (!kv) {
  await it.end()
} else {
  const [key, value] = kv
}
  1. for await...of
for await (let [key, value] of db.iterator()) {
  // no need to call end
}

cc @chjj @peakji


Previous discussions:

vweevers commented 5 years ago

Ah. Implementations like memdown that don't need an explicit end() call can implement asyncIterator themselves without an async generator, thus avoiding syntax errors in older runtimes. The level-js iterator currently does need an explicit end() but that will change with https://github.com/Level/level-js/issues/86.

So we don't have to do it in userland. The strategy is:

vweevers commented 3 years ago

Superseded by #379.