4 ms·
The saving grace of JavaScript's everything-is-async, single threaded model was that it was just slightly less difficult to reason about than multiple threads a
by ryandvm 10y ago
The saving grace of JavaScript's everything-is-async, single threaded model was that it was just slightly less difficult to reason about than multiple threads and shared state. (Though I'd say that's debatable...)
My guess is that, despite the sugar coating that JavaScript's async internals have received of late, writing stable multi-threaded code with JavaScript is going to be hard.
JavaScript now has the safety of multi-threaded code with the ease of asynchronicity!
- AgentME 10y agoSharedArrayBuffer only allows plain typed (byte) arrays to be shared at least. Arbitrary javascript objects can't be shared, so there's a very clear division about what can get affected by other threads and what can't. You don't have to worry about whether existing libraries are thread-safe, etc.
- Klathmon 10y agoNot only that, but if you don't need "Shared" array buffers (meaning more than one thread using it at once) you can use "Transferrable" [1] ArrayBuffers. It's just a zero-copy transfer to a worker (or from a worker) but it makes sure the "sender" doesn't have access to the memory any more. It's incredibly easy to use, avoids all the common issues and pitfalls with shared memory, and being zero-copy it's stupidly fast. Obviously it's not a replacement for true shared memory, but i've used it in the past to do some image processing in the browser (broke the image into chunks, and transferred each chunk to a worker to process, then return and stitch them all back together). [1]https://developer.mozilla.org/en-US/docs/Web/API/Transferable https://developer.mozilla.org/en-US/docs/Web/API/Transferabl...
- pfooti 10y agoThat's pretty rad - the vast majority of what I would see myself wanting to do in a multithreaded javascript world would be limited to something with transferrable arraybuffers. Like: "hey, worker, go do some work and lmk when you're done". Moving big chunks of memory around in ways that atomically only ever have one allowed accessing thread would be plenty.
- yoklov 10y agoI thought this too, but the fact that you can't send only a chunk of an array buffer is a huge limitation. It basically limits you do using a background thread to do something, instead of dividing the work among many (well, you can, but you loose most of the benefit of transferrable).
- Klathmon 10y agoWell you can still divide the work among many workers, you just need to incur the cost of copying/splitting the buffer before you start sending them off. In most cases you know how many workers you want at the start of the program, so that cost of splitting/merging only happens once (and you can do that splitting/merging in a worker to avoid hanging the main thread) and then you can pass those chunks around freely.
- yoklov 10y agoFor workloads like graphics, the cost of splitting/merging happens each time.
- taurath 10y agoUntil the point that someone makes the SharedJSON library to store JS objects in binary that is!
- Lerc 10y agoWhy is everything-is-async so entrenched in JavaScript? I'd love to have pre-emption and blocking IO in JavaScript but it seems to have been thoroughly excluded by design. What is the reasoning behind this?
- actsasbuffoon 10y agoIf you've ever used EventMachine in Ruby, or Twisted in Python, you've probably encountered the reason. Blocking has simple semantics, but it's hard to scale. Everything-is-async is a little more complicated, but scales nicely. The problem is when you combine the two, you only get the worst of both approaches. If most things are async, and you've only got one thread, and you block that thread, then your whole app is blocked. Now you've got the scaling problems that come with blocking, and the complexity that comes with async.
- Lerc 10y agoWell preemption and blocking should go hand in hand. The distinction of whether or not that's multi-threading is more of a semantic argument. I'd consider them the Amino acids that the multi-threading protein is made of. The entirely async model means that if something accidentally endless loops, it kills everything. The only reason why we get the "This script is taking a long time" is because some preemption is provided as some magic beyond the scope of the JavaScript itself.
- AgentME 10y agoUnless you're using webworkers, then javascript runs in the UI thread. If you do blocking IO in the UI thread, then things freeze.
- Lerc 10y agoThat's the problem in a nutshell, It needn't be that way. Blocking IO is just one aspect. Anything that is not instantaneous is blocking. Without the ability to preempt something taking a long time you will always be prone to the user interface freezing. Methods like Array.map() are specifically designed to manage bulk operations immediately, which, without preemption, is at odds with a design where the user interface should perform with the lowest latency.