Hacker News new | ask | show | jobs
by SebastianKra 1080 days ago
I really, really love Observables as an imperfect solution in an imperfect world, but I don't think they will solve reactivity.

The main issue is, that it becomes a nightmare to transmit and compose meta-information. An example would be the fetchStatus of ReactQuery [1].

I way too often end up in situations like this:

  .map {
    unwrapMetaData
    ...
    rewrapMetaData
  }
  ...
  .map {
    unwrapMetaData
    ...
    rewrapMetaData
  }
  .switchMap {
    // unwrap metadata and wrap it in an observable
    combineLatest(...) // have fun juggling an array of nested monads :)
  }
I wonder if it is possible to create a mixture between React hooks and async/await. Since you tend to work in one big scope, you could ignore the meta-info until you need it.

  async live function() {
    const { value, meta } = observe getValue(...) // suspends when loading, throws on error
    // work with values
    const multipleValues = observe Observe.all(...map(i => ...))
    // more work
    // evaluateMetadata
  }
[1]: https://tanstack.com/query/v4/docs/react/guides/queries#fetc...
2 comments

You can already combine hooks with something like Rx using the useSyncExternalStore hook.

I’ve worked on very complex Rx code bases. I like Rx, but it gets it be a huge pain the debug when you have very complicated chains. I haven’t used hooks too much, but from what I’ve seen the default behavior is to “do the wrong thing” which makes them very annoying to work with. The implementation of hooks is also very hacky. Like you can’t create a hook inside an if statement. That’s crazy.

I've had some success with writing Async Generator functions in mixed RxJS/IxJS pipelines.

  async *function someMapOperation() {
    const { value, meta } = await getValue(…)
    doSomething(meta)
    yield value
    for await (const { value, meta } of AsyncIterableX.from(mergeAll(…).pipe(takeUntil(…)))) {
      doSomething(meta)
      yield value
    }
    // …
  }
(I've done similar things in C#, as well, with its Rx/Ix pair.)

You are right, there are still good cases where being able to write the "state machine" of a complex flow as an async (generator) function makes it a lot easier to reason with. The nice thing is that Observables work well with AsyncIterables and a pipeline doesn't have to be just one or the other.