-
Notifications
You must be signed in to change notification settings - Fork 35
Closed
Description
The documentation at Effection Collections mentions that Stream corresponds to AsyncIterable, but in practice, AsyncIterable -> AsyncIterator does not require await during usage:
const delay = (x: number) => new Promise(r => setTimeout(r, x));
(async () => {
const stream: AsyncIterable<number> = (async function* () {
await delay(100)
yield 1
await delay(100)
yield 2
await delay(100)
yield 3
})();
const subcription1 = stream[Symbol.asyncIterator]() // No `await` on the stream itself
// const subcription2 = ...
console.log(await subcription1.next())
// ....
})()The example in the Effection documentation is also confusing:
let subscription1 = yield* channel;
let subscription2 = yield* channel;There are two different subscriptions created here, and it feels like merely using yield* to wait for an Operation<X> creates a new task, whereas await waiting for a Promise<X> does not.
Nowadays, for the same functionality, I think the following expression in Effection is better:
import { main, createChannel } from 'effection';
await main(function*() {
let channel = createChannel();
// the channel has no subscribers yet!
yield* channel.send('too early');
let subscription1 = channel.subscribe();
let subscription2 = channel.subscribe();
yield* channel.send('hello');
yield* channel.send('world');
console.log(yield* subscription1.next());
//=> { done: false, value: "hello" }
console.log(yield* subscription1.next());
//=> { done: false, value: "world" }
console.log(yield* subscription2.next());
//=> { done: false, value: "hello" }
console.log(yield* subscription2.next());
//=> { done: false, value: "world" }
});Hmm, what about Stream? Maybe the signature of Stream should be Stream<T> = () => Subscription<T>. This way, it would be analogous to AsyncIterable and AsyncIterator.
Metadata
Metadata
Assignees
Labels
No labels