-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
48 lines (40 loc) · 1.06 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
'use strict'
const keysAsyncIterator = (redis, opt = {}) => {
const {
batchSize,
match,
} = {
batchSize: 20,
match: null,
...opt,
}
let pCursor = Promise.resolve('0')
let bufferedKeys = []
let end = false
const iterate = async () => {
if (bufferedKeys.length === 0) {
if (end) return {done: true, value: null}
const op = pCursor.then(cursor => {
return match !== null
? redis.scan(cursor, 'COUNT', batchSize, 'MATCH', match)
: redis.scan(cursor, 'COUNT', batchSize)
})
// set pCursor immediately, `await` Promise later
pCursor = op.then(scanRes => scanRes[0])
const [cursor, newBufferedKeys] = await op
bufferedKeys = bufferedKeys.concat(newBufferedKeys)
if (bufferedKeys.length === 0) {
// stop immediately
return {done: true, value: null}
}
end = cursor === '0' // stop in next iteration
}
return {done: false, value: bufferedKeys.shift()}
}
return {
next: iterate,
// support async iterable API
[Symbol.asyncIterator]: () => keysAsyncIterator(redis, opt),
}
}
module.exports = keysAsyncIterator