For Await Iterables
`for await...of` over every accepted iterable shape, and the sync [Symbol.iterator] protocol. No network — runs offline and deterministically.
// A sync generator in `for await` (the spec's CreateAsyncFromSyncIterator):
// plain yields are identity-awaited, promise yields await to their values.
function* nums(): number {
yield 1;
yield 2;
yield 3;
}
async function work(n: number): Promise<number> {
return n * 10;
}
function* jobs(): Promise<number> {
yield work(1);
yield work(2);
}
// A class implementing the *sync* iteration protocol by hand —
// `[Symbol.iterator]()` returning an iterator whose `next()` yields the
// spec's `{value, done}` shape. Works in plain `for...of` too.
class Countdown {
n: number;
constructor(start: number) { this.n = start; }
[Symbol.iterator](): Countdown { return this; }
next(): { value: number; done: boolean } {
if (this.n <= 0) { return { value: 0, done: true }; }
const v = this.n;
this.n = this.n - 1;
return { value: v, done: false };
}
}
async function* agen(): number {
yield await work(4);
yield await work(5);
}
async function main(): Promise<void> {
for await (const n of nums()) { console.log(n); } // 1 2 3
for await (const v of jobs()) { console.log(v); } // 10 20
// Map values / Set elements, same shapes as sync for-of.
const m = new Map<string, number>();
m.set("a", 5);
m.set("b", 7);
for await (const v of m) { console.log(v); } // 5 7
const s = new Set<string>();
s.add("hi");
s.add("yo");
for await (const t of s) { console.log(t); } // hi yo
// An object literal with a [Symbol.asyncIterator] member — arrow-valued or
// method shorthand — is a for-await iterable.
const obj = { [Symbol.asyncIterator]: () => agen() };
for await (const x of obj) { console.log(x); } // 40 50
for (const x of new Countdown(3)) { console.log(x); } // 3 2 1
for await (const x of new Countdown(2)) { console.log(x); } // 2 1
}
main();View source on GitHubexamples/async/for_await_iterables.ts