0

以您的普通谷歌桌面小工具为例。添加以下代码:

 debug.trace("go!");
 for (var i = 0; i < 100000000; i++) { // google desktop stops responding
      j = 12 * i;
 }
 debug.trace("finished");

所有谷歌桌面小工具在此期间锁定/冻结,包括运行代码的小工具(正常的双班快捷方式不起作用,您不能移动任何小工具或以任何其他方式与它们交互;系统托盘图标是响应式的,但不执行任何操作 - 例如,在代码完成之前不会加载选项页面)。

我正在寻找解决这种一般情况的方法(我的情况是我通过一个需要很长时间才能返回的 DLL 进行外部函数调用,请参阅gmanifest 'install' 元素)。

通过 setInterval / setTimeout 触发调用(/上面的代码)似乎没有任何区别,在长时间调用发生时,通常由计时器调用的任何代码也不会被执行。

我假设这是可能的,因为当您尝试使用以下代码代替繁忙循环或我的阻塞外部函数调用时,没有任何锁定:

 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

我不知道这三种情况有什么区别。有什么想法,更重要的是,有什么办法吗?

想法:

  • 繁忙的循环本身并没有阻塞,但只是用尽了所有处理器时间,因此没有任何反应,因此不具有代表性(似乎不太可能)[编辑:不,它正在阻塞]

  • DLL 或我使用它的方式分别损坏或错误(可能是,如果需要,我可以添加更多详细信息)[编辑:似乎不是,只是一个正常的阻塞调用]

  • 谷歌小工具“知道” wscript.shell 并在“运行”被阻塞时继续运行(似乎不太可能)[编辑:未回答!]

  • 我可以为阻塞代码显式生成一个工作线程(我在小工具中找不到显式线程控制的任何内容)[编辑:不可能;javascript有一个线程]

  • 在外部程序中结束块调用,轮询文件以获取状态更新(见答案)

4

1 回答 1

0

Javascript 有一个执行线程和一个调用堆栈。您不能停放该线程,保存调用堆栈并让它稍后恢复。

保持响应的 JavaScript 方法是确保在执行准备好时获得回调。根据经验,永远不要占用线程并等待某事发生。

这就是为什么 AJAX (异步)中有一个 A - 即使您可以制作 synchronous XmlHttpRequest,它通常被认为是一个坏主意。

于 2010-11-21T21:37:24.710 回答