Skip to content

The behavior of stream seems somewhat odd; perhaps it shouldn't be Operation<X> #976

@iplaylf2

Description

@iplaylf2

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())
    // ....
})()

typescript playground

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions