Closed ejez closed 3 years ago
The fromArray
operator synchronously pushes values using a small trampoline scheduler. It cycles through values as long as values are pulled. All sinks, like subscribe
start sending Pull
signals as soon as they receive Start
.
That leaves the detail of when onStart
runs. It actually forwards the Start
signal before running the callback, which then means that all values are pushed before this function actually runs in this exceptional case.
The reason for that implementation detail is that if onStart
ran before Start
was forwarded then we run the risk of executing it before the source has fully started. That's a minor gotcha, but it's currently necessary given the risks of Start
not fully propagating, since it's often used as a signal to set up other states.
@kitten Thanks for the explanation!
I was using onStart
to set a fetching
state in urql
, and was resetting it in onEnd
and when a result is received in subscribe
. It was working for the first fetch, but breaks when the result is pushed synchronously from cache afterwards, due to the onStart
callback executed last. I was not expecting that and it took me a little bit of time to find about the unexpected execution order.
I hope this issue will be of benefit for other users, but an entry in the docs (time permitting) would be appreciated.
Thanks for the hard work on this library!
Yep, in urql
we typically get around this by setting fetching
to true
before the source is activated/subscribed to. Logically, there are two phases:
Start
signal / before subscriptionStart
signal / setup completeThe onStart
takes care of the second phase, but the first phase should simply be implemented as synchronous/imperative code before using the source.
Thanks!
What i did, is adding a condition for setting fetching
to true
in onSart
(only when there is no data, ie first fetch). I will change it as per your suggestion, as it seems onStart
is not the natural place for setting the fetching state.
yea, sounds good 👍 I'll close this for now, since I think the question itself is addressed.
The problems here and ambition is basically always with synchronous streams. The synchronous support in Wonka allows us to apply some nice tricks in urql, but that does come with some caveats. Synchronous events are just very different from asynchronous as it'll always deal with an exact order.
In the following example I was expecting "onStart" callback to be invoked first, but noticed it was run last:
https://codepen.io/ejez/pen/NWjWBoJ
result:
From the docs:
Many thanks.