Race Condition
borislobanov92 opened this issue · 0 comments
From Sergey M.:
What happens under the hood:
await clientPromise.current
is called by the immediate data request. The current value is undefined at this moment of time, so the await continues the execution very quickly.
clientPromise.current = client.init()
is called. The clientPromise.current
value is filled with the JS agent loading promise.
return client.getVisitorData()
is called very soon after. The agent loading promise was not awaited, so the agent hasn’t loaded and the promise is rejected with a FPJSAgent hasn't loaded yet error.
The step 1 is executed before the step 2 (expected to be vice-versa I suppose) because React executes useEffect in order of element parenthood: from children to parents. The useVisitorData
hook (that starts loading the data immediately) is a child of a FpjsProvider
element (that initializes the client).
I did a quick fix to test my hypothesis. I replaced this useEffect with a useLayoutEffect to make the step 2 go before the step 1, and the error went away. This is a dirty solution, I don’t recommend it.
The error may not happened with the old version of JS agent because it loads almost instantly.
I’d implement a more robust solution that works no matter when getVisitorData or getData were called, even during an initial rendering.
Also I recommend handling JS agent loading errors because they cause the error too.
https://fpjs.myjetbrains.com/youtrack/issue/DASH-1039
PR: #8