9 ms·
Here’s [1] a blog post introducing Crank.js. It goes into detail as to why the library exists. The main motivator for the creator seems to be that they really d
by migueloller 6y ago
Here’s [1] a blog post introducing Crank.js. It goes into detail as to why the library exists. The main motivator for the creator seems to be that they really disliked the suspense API and wanted to offer a better way using JS generators and async/await.
[1] https://crank.js.org/blog/introducing-crank https://crank.js.org/blog/introducing-crank
- ethanwillis 6y agoHoly hell. I didn't realize this. This is nightmare fuel and the blog post you linked is leveling some really good criticism. My favorite part is where he linked to a Github issue where the React team instead of responding with a real answer just repeated their manta "Suspense will solve everything" and closed the issue. I know "open source devs don't owe you anything." But I've noticed that sentiment is now being used in a lot of open source projects, especially the well funded ones by big Corps, to just shutdown anything that derails whatever their underlying motivations are. I mostly abandoned the effort and any sort of greenfield React development, when I came to understand what Suspense was and how unwieldy it would have been to incorporate Suspense into the hooks I had written. As of April 2020, the mechanism behind Suspense is for components which make async calls to throw a promise while rendering to indicate that the component is doing something asynchronously. “Throw” as in the way you would “throw” an error in JavaScript with the throw operator. In short, React will attempt to render your components, and if a thenable is thrown in the course of rendering, React will catch it in a special parent component called Suspense, render a fallback if sufficient time has elapsed, and then when the promise has fulfilled, attempt to render the component again. I say “as of April 2020,” because the React team has consistently said the exact details of the Suspense API might change, and has used this declaration to preempt any possible criticisms of this mechanism
- hombre_fatal 6y agoWell, I don't think this is fair, either. As someone points out in the thread before making some good points to OP, this topic is discussed ad nauseam in React's github issues and elsewhere. There are many good discussions online about this and all the different solutions out there with different trade-offs. And the Suspense system is what the React team came up with to solve it. I don't see how someone wanting to rehash the discussion requires any other answer than "we're solving this with X, it's just not yet available." This is one of the most common trope of any sort of forum system, github issues included: everyone thinks they're the first person to broach a topic, yet everyone else has seen it 1000s times.
- earthboundkid 6y agoReally great origin story for either a JS framework or a Batman villain…
- lhorie 6y agoDan Abramov responded to this on r/javascript and mentioned that the rationale for Suspense wasn't so much to chase some academic concept of purity (and shoehorning caching in to the system to make it happen), but rather that Suspense was there to support a pre-existing need for a cache for cases like snappy back/forward routing. Personally, I'm a bit on the side of Crank's author that I feel that the direction React has been taking wrt async support feels weird. Can't really put into words, but if I had to try, I'd say React's answer to async feels like something getting lost in translation. There are certainly interesting ideas being explored, for example, in Dan's blog post about algebraic effects[1]. But I feel that Crank's approach feels like a more elegant way of "translating" that concept into JS than the whole promise-throwing thing that React seems to be pursuing. [1] https://overreacted.io/algebraic-effects-for-the-rest-of-us/ https://overreacted.io/algebraic-effects-for-the-rest-of-us/
- k__ 6y agoWasn't one point also that generators and such are contagious?
- lhorie 6y agoasync is contagious, generators are not. const foo = async () => {} const mustAlsoBeAsync = async () => console.log(await foo()) const gen = function* () { let n = 10 while (n) yield n--; } const doesntNeedToBeGenerator = () => { for (const n of gen()) console.log(n) }
- lilactown 6y agoI enjoyed reading this blog post, and the perspective that the author brings. The notion that a cache is a big ask is novel to me, but I think it is a good point that it does complicate things more for simpler cases. However, I would like to hear the author's thoughts on Concurrent Mode in general, and how Crank.js addresses the same issues. There's no mention here of time slicing, which is what Concurrent Mode really unlocks. IIUC Suspense was discovered, not invented, after implementing React Fiber and exploring the knock-on effects of being able to restart rendering from a place in the component tree. React's insistence on rendering being "pure" is not dogma; it is an attribute that unlocks the ability to pause and resume rendering at any node in the component tree... like if an important update from a keyboard press comes in that you need to handle right now. This means that when CPU is scarce, jank can be alleviated by prioritizing user input and other high priority updates. There's a tweet out there by sebmarkbage that gives a slightly cryptic response to using generators, but the gist that I remember is that because generators are mutable, you don't get the properties you need to arbitrarily pause and resume a component just like it was when you paused rendering it. The author claims that this is just dogma, but I believe (and the React team believes too) that time slicing provides a measurable benefit to the user experience. This point is contentious still; Rich Harris of Svelte fame claims that _doing less work_ is more important than prioritizing it. But the author here doesn't address this at all, instead claiming architectural simplicity is its own goal. I'm excited to see alternatives to React come out and generate excitement, and I'm very interested to see where Crank.js continues to evolve. My hope is that in 5 years we'll know way more about all of these questions than we do now, and we'll be able to put those into practice in better frameworks, delivering better applications.
- lhorie 6y agoAs an outsider, I honestly feel that there's a strong difference in opinions between Dan and Sebastian. One doesn't need to reason too hard about the purity thing: Dan himself admits hooks were criticized (accurately) for being impure. On the other end of the discussion, the claim about impurity preventing prioritization is very weird, because simply going async will shuffle the rest of your rendering further out in the microtask queue, giving the opportunity for event handlers to fire half way through a vdom render pass, effectively prioritizing user input.