How to allow a google desktop gadget to update its UI (handle user input) whilst the underlying code is busy/blocked?
Take your average google desktop gadget. Add the following code:
debug.trace("go!"); for (var i = 0; i < 100000000; i++) { // google desktop stops responding j = 12 * i; } debug.trace("finished");
All google desktop gadgets lock up / freeze for the duration, including the gadget the code is running in (the normal double-shift shortcut doesn't work, you can't move any gadgets or interact with them in any other way; the systray icon is responsive, but doesn't do anything - e.g. the options page isn't loaded till the code has开发者_高级运维 finished).
I'm looking for a way around this general situation (my case is I'm making external function calls via a DLL that take a long time to return, see gmanifest 'install' element).
Having the calls (/ above code) triggered via setInterval / setTimeout doesn't seem to make any difference, nor does any code that would normally be called by a timer get executed whilst the long call is taking place.
I'm assuming this is possible, because when you try the following code in place of the busy loop or my blocking external function call, nothing locks up:
var wsh = new ActiveXObject("WScript.Shell"); wsh.run("cmd.exe",1,true); // true = block until program has exited // UI responds in this period debug.trace("finished"); // occurs when cmd.exe is closed
I don't know what the difference between these three cases is. Any ideas, and more importantly, any way around it?
Thoughts:
The busy loop isn't blocking as such, but just using up all processor time so nothing happens hence isn't representative (seems unlikely) [edit: no, it is blocking]
The DLL or way I'm using it is broken or wrong, respectively (could be, I can add more details if needed) [edit: seems not, just a normal blocking call]
google gadgets "knows about" wscript.shell and carries on going whilst "run" is blocking (seems unlikely) [edit: unanswered!]
I could explicitly spawn a worker thread for the blocking code (I can't find anything on explicit thread control in gadgets) [edit: not possible; javascript has a single thread]
Wrap up the block call in an external program, poll file for status updates (see answer)
Javascript has exactly one executing thread with one call stack. You can't park that thread, saving away the call stack and have it resume later.
The javascript way to keep things responsive is to make sure you get a callback when the execution is ready. As a rule of thumb, never hog the thread and wait for something to happen.
This is why there's an A in AJAX (asynchronous) - even though you can make synchronous XmlHttpRequest
, it's generally considered a bad idea.
精彩评论