Skip to content

Keep track of iterator end in _nextv() fallback #19

@vweevers

Description

@vweevers

Currently, nextv() can only signal the natural end of an iterator by yielding an empty array. In the fallback _nextv() implementation below, when _next() signals end by yielding an undefined key and/or value (line 147), this means _nextv() does not signal end (line 148, unless acc is empty). Consequently, a consumer will call nextv() again, which means we call _next() again (line 160) which has already signaled end.

Whether that's a problem depends on implementation. It is in many-level (the replacement for multileveldown that I'm working on atm, and can easily have its own fix) and could be in others too. It's not a problem for implementations written so far (memory-level, classic-level, browser-level) because those implement their own optimized _nextv().

Solution: set a new private kEnded property to true on line 148, and check that it's false before calling _next(). A seek() should reset it to false. Maybe use kEnded in more places, as a general protection.

_nextv (size, options, callback) {
const acc = []
const onnext = (err, key, value) => {
if (err) {
return callback(err)
} else if (this[kLegacy] ? key === undefined && value === undefined : key === undefined) {
return callback(null, acc)
}
acc.push(this[kLegacy] ? [key, value] : key)
if (acc.length === size) {
callback(null, acc)
} else {
this._next(onnext)
}
}
this._next(onnext)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status

    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions