4 ms·
Why not just use promises? side note: legit question, I don't do web/app dev
by nostrebored 7y ago
Why not just use promises?
side note: legit question, I don't do web/app dev
- Kuinox 7y agoBecause JS is single threaded. If a task is too big you need to split it or the UI can't be updated until the task is done.
- doomslice 7y agoPromises still run on "the main thread" so a CPU intensive task in a promise is still going to block things. You could use a promise if you delegated your CPU task to another process or some C code that did actual threading. I believe you'd use Workers (WebWorkers?) https://developer.mozilla.org/en-US/docs/Web/API/Workers https://developer.mozilla.org/en-US/docs/Web/API/Workers to actually do it off the main thread entirely inside JS.
- earthboundkid 7y agoPromises still run in the main thread. You could try to use a web worker, but then you run into the problem that they don't have shared memory, so you need to pass data back some other way.
- earthboundkid 7y agoIndexedDB runs on web workers, so that might be a good way to push the work off the main thread but still share the result.
- RussianCow 7y agoPromises are a way to deal with async code. Parsing JSON is synchronous and CPU-bound, so promises offer no benefit. And since web pages are single-threaded[0], there isn't really any way you can parse JSON in the background and wait on the result. [0]: There is now the Web Workers API which does allow you to run code in the background. I've never used it, but I have heard that it has a pretty high overhead since you have to communicate with it through message passing, so it's possible you wouldn't actually gain anything by using it to parse a large JSON object. https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers...
- Klathmon 7y agoBecause JSON.parse blocks the thread it's in, and JS is single threaded [1]. So even if you put it behind a promise, when that promise actually runs, it will block the thread. In essence, using promises (or callbacks or timeouts or anything else like that) allows you to delay the thread-blocking, but once the code hits `JSON.parse`, no other javascript will run until it completes. And since no other javascript will run, the UI is entirely unresponsive during that time as well. [1] Technically there are web-workers, and I looked into them to try and solve this problem. Unfortunately any complex-objects that get sent to or from a worker need to be serialized (no pass-by-reference is allowed except for a very small subset of "C style" arrays called TypedArrays). So while you could technically send the string to a worker and have the worker call `JSON.parse` on it to get an object, when you go to pass that object back the javascript engine will need to do an "implicit" `JSON.stringify` in the worker, then a `JSON.parse` in the main thread. Making it entirely useless for my usecase. But continuing with that same thought process, I very nearly went for an architecture that used a web-worker, did the `JSON.parse` in the worker, then exposed methods that could be called from the main thread to get small amounts of data out of the worker as needed. Something like `worker.getProperty('foo.bar.baz')` which would only take the parsing hit for very small subsets of the data at a time. But ultimately the oboe.js solution was simpler and faster at runtime.
- nostrebored 7y agoThank you for the excellent explanation! I think of js entirely from a node.js perspective where I conceptualize it as an async task. Is this also wrong?
- Klathmon 7y agoNode suffers from the same issues, but it's generally not as noticable in most cases. A similar situation in node would cause the server to not be able to respond to any other requests during the `JSON.parse` execution. But in the Node world, you have more options for how to get around those problems (like load balancing requests among several node processes). But both server-side and client-side JS use the same system, the event loop. It's basically a message-queue of events that get stacked up, and the JS engine will one at a time grab the oldest event in that queue and process it to completion. Anything "async" will just throw a new event into that queue of events to be processed. The secret sauce is that any IO is done "outside" the JS execution, so other events can be processed while the IO is waiting to complete. Take a look at this link, or search up the JS event-loop if you want to get a better explanation. It's deceptively simple. https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop https://developer.mozilla.org/en-US/docs/Web/JavaScript/Even...
- Rapzid 7y agoJSON.parse is not interruptible. All the answers about promises and single threading are interesting but that's the crux of the issue.