-
Notifications
You must be signed in to change notification settings - Fork 206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
events from fromEvent + scan out of order #491
Comments
I found out that if I move it inside a setTimeout(function() {
store.dispatch({ type: 'SET_FOOBAR', foobar: 3 })
store.dispatch({ type: 'SET_FOOBAR', foobar: 5 })
}, 0) I guess there's something going on with how it queues up events in the event loop |
I have experienced this issue when using |
@Risto-Stevcev so that's why you get the unexpected result until you wrap your dispatching into a setTimeout. |
Would be better to throw some error in cases like this. It is a silent error and really hard to track down. |
It is not an error. In fact, it behaves as expected. It would be wrong to “throw some error in cases like this.” Within a function f, a failure is an error if and only if it prevents f from meeting any of its callee’s preconditions, achieving any of f’s own postconditions, or reestablishing any invariant that f shares responsibility for maintaining. There are three different kinds of errors:
Any other condition is not an error and should not be reported as an error. |
There's something odd about this behavior though. I've tried doing similar things with |
Most basically uses Whereas other libraries will emit the default scan value at the time of subscription - ensuring it occurs before any others could possibly make it through. This may seem odd at first, but this guarantee that events do not occur in the same call stack as subscription makes your applications less prone to errors that occur due to the order in which you subscribe to your streams. |
I still think this is very confusing. Maybe it is obvious to you but for such a beginner in FRP like myself, it was really hard. I didn't believe my eyes when I've seen that the initial value happened first. It should be at least mentioned in the API docs, with bold font and examples. |
Can you be more specific (maybe an example) on how this prevents errors? Emitting the default scan value at subscription seems like the correct design decision to me |
@Frikki Not sure I would call it an error either, but |
I can't see exactly why this is happening in this case, but I've experienced the initial scan value arriving out of order when the time value of the initial inbound event is generated before the scan source is run. The scheduler schedules the initial value based on the current time, and if the inbound value is delivered to the scan sink in the same call stack, you end up with two scheduled tasks, the second having an earlier schedule time than the first, which causes the scheduler to arrange for the second to be delivered before the first. |
As I see it, @axefrog, the culprit is what @davidchase wrote here, and is aligning with your comment, too. @Risto-Stevcev, I still think that
If we, as @TylorS mentions in his comment, didn’t ensure that events occur on a different callstack than the subscription, we would see race condition issues in many cases. This relates to this issue, and the solution chosen was to develop |
Is there a downside to modifying the implementation of That way none of this would occur and would ensure that all events occur on a different callstack than the subscription |
@Risto-Stevcev, in my testing, |
@ryanlaws DOMHighResTimeStamp is in ms not mcs, could also be that you included the function declaration by accident: const f = () => 123
const timeout = () => { performance.mark('fn-start'); setTimeout(f, 0); performance.mark('fn-end') }
timeout()
performance.measure('fn', 'fn-start', 'fn-end')
performance.getEntriesByName('fn')[0].duration
// vs
timeout2 = () => { performance.mark('fn2-start'); f(); performance.mark('fn2-end') }
timeout2()
performance.measure('fn2', 'fn2-start', 'fn2-end')
performance.getEntriesByName('fn2')[0].duration On my machine the difference is about 0.06-0.08 ms, which is 60-80 microseconds. That's very negligible |
@Risto-Stevcev Thanks for the test snippet. It's showing a difference of just shy of .1ms on my machine. It's very possible that my test was flawed - I believe I was directly calling |
I have the following code:
which strangely enough prints the initial state as the last thing to the console:
I would expect it to print the inital state as the first thing, like this:
is this a bug?
I'm trying this on 1.7.0. I've tried this code with rxjs and xstream and they both work like I expected it to
The text was updated successfully, but these errors were encountered: