Slide 34
Slide 34 text
e.g. Observable -> AsyncIterable (PoC)
class ObservableToIter {
constructor(source) {
this._buffer = [];
this._resolverCache = [];
this._done = false;
this._current = 0;
source.subscribe((v) => {
this._buffer.push({ ok: true, value: v, });
const lastIndex = this._buffer.length - 1;
const resolver = this._resolverCache[lastIndex];
if (resolver !== undefined) {
resolver({ done: this._done, value: v, });
this._resolverCache[lastIndex] = undefined;
}
}, () => {}, () => {
this._done = true;
for (const resolver of this._resolverCache) {
if (resolver === undefined) { continue; }
resolver({
done: true,
});
}
this._resolverCache = [];
});
}
next() {
const done = this._done;
if (done) {
return Promise.resolve({ done });
}
const current = this._current;
this._current++;
const result = this._buffer[current];
if (result !== undefined && result.ok) {
return Promise.resolve({
done,
value: result.value,
});
}
else {
return new Promise((resolve) => {
this._resolverCache[current] = resolve;
});
}
}
[System.asyncIterator]() { return this; }
}
const source = Rx.Observable.create((o) => {
const buffer: any = [];
for (const i of [1, 2, 3, 4, 5]) {
buffer.push(new Promise((r) => {
window.setTimeout(() => {
r();
o.next(i);
}, i * 1000);
}));
}
Promise.all(buffer).then(() => o.complete());
});
const iter = new ObservableToIter(source);
await iter.next() // done: false, value: 1
await iter.next(); // done: false, value: 2
await iter.next(); // done: false, value: 3
await iter.next(); // done: false, value: 4
await iter.next(); // done: false, value: 5
await iter.next(); // done: false, value: undefined