Created
June 22, 2020 07:57
-
-
Save bellbind/bf6c4f41db1a2691cd456bd4a3c36126 to your computer and use it in GitHub Desktop.
[ECMAScript] array with async iterator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Notifier = class { | |
constructor() { | |
this.waits = new Set(); | |
} | |
get wait() { | |
let d = {}; | |
const p = new Promise((f, r) => { | |
d.r = r; d.f = f; | |
}); | |
this.waits.add(d); | |
return p; | |
} | |
notify() { | |
for (const {f} of this.waits) f(); | |
this.waits.clear(); | |
} | |
close() { | |
for (const {r} of this.waits) r(); | |
this.waits.clear(); | |
} | |
}; | |
const notifiers = new WeakMap(); | |
export const AsyncArray = class extends Array { | |
constructor(...args) { | |
super(...args); | |
notifiers.set(this, new Notifier()); | |
} | |
push(...args) { | |
const r = super.push(...args); | |
notifiers.get(this).notify(); | |
return r; | |
} | |
close() { | |
notifiers.get(this).close(); | |
} | |
async *[Symbol.asyncIterator]() { | |
let i = 0; | |
try { | |
for (let i = 0; ; i++) { | |
while (i >= this.length) { | |
await notifiers.get(this).wait; | |
} | |
yield this[i]; | |
} | |
} catch {} | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {assertEquals} from "https://deno.land/std/testing/asserts.ts"; | |
import {AsyncArray} from "./async-array.js"; | |
Deno.test("async array", async () => { | |
const a = new AsyncArray(); | |
a.push(0); | |
a.push(1); | |
a.push(2); | |
(async () => { | |
for (let i = 3; i < 6; i++) { | |
await new Promise(f => setTimeout(f, 100)); | |
a.push(i); | |
} | |
a.close(); | |
})(); | |
const r = []; | |
for await (const e of a) { | |
r.push(e); | |
} | |
assertEquals(r, [0,1,2,3,4,5]); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment