I know, I know, it's not a good design. Non-blocking setTimeout or setInterval are a way better approach, but to implement non-blocking, you need to refactor the whole code to have callback points in my scenario. Let me explain:
- I have a function that aims to fetch an object from a cache (storage)
- If the object is available, I take it
- When the object is not available, I request for it and wait until available by polling, with an expiration counter/time. At one point (not too far) it will be available and then I return to the caller
I cannot implement a callback because the chain of calls (stack) is very deep and complex and it is simply impossible to refactor all of the code to use asynchronous callbacks/etc. In this specific case I really need a single threaded blocking loop.
Now here comes the question:
I dont simply want to use a simple for-loop with a counter. This would consume too many CPU cycles and would cause computer fans to fire up ( even if for a few seconds ). I am looking to find out what is the slowest javascript commands (or set of commands) that I can use as a blocking approach such as:
while ( needToContinue ) {
slowestCommandOrFunction();
needToContinue = checkIfNeedToContinue();
}
-
In JavaScript in web browsers, there is simply no such thing. In Node.js, you could probably do something like use a special "slow" device and synchronous I/O operations to effectively pause execution. (edit Explosion Pills wisely notes the existence of synchronous XHR)Pointy– Pointy2013年02月23日 14:39:57 +00:00Commented Feb 23, 2013 at 14:39
-
3You are aware, that the browser will be unresponsive for the whole time you run this "blocking sleep" ?Sirko– Sirko2013年02月23日 14:41:52 +00:00Commented Feb 23, 2013 at 14:41
-
What you want is not what you need - JavaScript doesn't work that way. It runs on a single thread, shared with the rest of the page, so if you block, ALL JAVASCRIPT on the page gets blocked. UI code can't run on the side, you can't even update a progress bar. If your call chain is deep, you'll have to deal with the fact that "the resource is not available right now" is a returning state.Mike 'Pomax' Kamermans– Mike 'Pomax' Kamermans2013年02月23日 16:47:48 +00:00Commented Feb 23, 2013 at 16:47
-
thanks for your comments. After more testing I came to learn indeed, as you suggested, that the whole js engine is single threaded. In fact I assumed that the call to an ajax action would somehow allow my continued thread to obtain its answer, but it will only happen if the UI takes back the control and then the value will get updated from the response. Although I am a fan of asynchronous logic, many situations (code wise) are not suitable for that. I finally understand why Chrome had to come to live. Hopefully EcmaScript will set a threading specification...gextra– gextra2013年02月24日 14:15:08 +00:00Commented Feb 24, 2013 at 14:15
2 Answers 2
It sounds like it's an ajax request that you want to synchronize. You can do this with the third argument to XMLHttpRequest.open:
xhr.open('GET', url, false);
I still recommend that you take the time to refactor your code, though.
1 Comment
If you want to speed up the refactoring, you can just use streamlinejs. Basically, you have to compile your JS with streamlinejs, but in exchange, you can make sync functions async ones by just putting underscores in all parameter lists. E.g.
function foo() {
for (var i=0; i<10; i++) {
bar()
}
}
simply becomes
function foo(_) {
for (var i=0; i<10; i++) {
bar(_)
}
}
Also, in case you're using server-side javascript with nodejs, you can use fibers.