Handling refreshes when callback may be called either synchronously or asynchronously? #202
-
During my component set-up I subscribe to data using a GraphQL library (urql) that caches responses. If the result is in the cache, the library calls my callback synchronously. If it has to hit the network, the callback is called asynchronously. I store the query result in a variable and trigger a component refresh each time the callback is called. But since the callback can be called synchronously, this means sometimes What's the recommended way to handle this? For this case I can use Does that make sense? Or is there a better way I should be going about this? Edit: I'm not sure how this notion fits in with components where |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
Technically, this is not a runtime error but a console “error.” Refreshes which are detected to occur while components are already executing are turned into no-ops, because if we just re-executed the component, we’d likely end up with an infinite loop. At the same time I was seeing people write refresh calls directly in the main function anyways, so I added this console error to discourage the practice. I admit that I didn’t really think about the use-case of a zalgo-unleashing callback, but I can’t say that I care too much that a warning is emitted when you have an API whose callbacks run synchronously or asynchronously. Essentially, what’s happening is that a cache hit results in your callbacks being called synchronously, while a cache miss results in your callbacks being called asynchronously. For a callback API, doing both from the same function is incredibly confusing for several reasons as the article describes. Ultimately, I think URQL designers thought they needed to update synchronously because of some perceived requirements, where it was unacceptable for a cache hit to produce a loading render. The thing is, successive DOM renderings which take place in a microtask loop are visually imperceptible, so I’m not sure why this is a requirement for GraphQL libraries at all. As an aside, requiring caches to return cached data synchronously severely limits the sort of backing storage and transport abstractions you can use. In short, if you wrap the API so that the callback always fires after a microtask, you will both avoid the warning from Crank, and your users will be none the wiser. I think wrapping the URQL API so it doesn’t fire synchronously is probably a good idea.
Care to expand on this? If you have a component which doesn’t yield in a loop, I’d imagine you’d need an incredible amount precision around when the component is actually executed. |
Beta Was this translation helpful? Give feedback.
Technically, this is not a runtime error but a console “error.” Refreshes which are detected to occur while components are already executing are turned into no-ops, because if we just re-executed the component, we’d likely end up with an infinite loop. At the same time I was seeing people write refresh calls directly in the main function anyways, so I added this console error to discourage the practice.
I admit that I didn’t really think about the use-case of a zalgo-unleashing callback, but I can’t say that I care too much that a warning is emitted when you have an API whose callbacks run synchronously or asynchronously. Essentially…