停止JavaScript执行而不锁定浏览器

停止JavaScript执行而不锁定浏览器,javascript,execution,Javascript,Execution,您是否能够在不锁定浏览器的情况下停止JavaScript执行?通常停止执行的方法是执行无限while()-循环,但对于FireFox,它会锁定浏览器,直到循环结束 你对此有什么看法? 我正在尝试覆盖window.confirm()以使用HTML实现我自己的对话框。我这样做是为了不必更改现有代码(这是一个相当大的代码库) 我需要能够停止执行,以允许用户输入;要像标准确认函数那样依次返回布尔值,请执行以下操作: if (confirm("...")) { // user pressed

您是否能够在不锁定浏览器的情况下停止JavaScript执行?通常停止执行的方法是执行无限
while()
-循环,但对于FireFox,它会锁定浏览器,直到循环结束

你对此有什么看法?


我正在尝试覆盖
window.confirm()
以使用HTML实现我自己的对话框。我这样做是为了不必更改现有代码(这是一个相当大的代码库)

我需要能够停止执行,以允许用户输入;要像标准确认函数那样依次返回布尔值,请执行以下操作:

if (confirm("..."))
{
    // user pressed "OK"
}
else
{
    // user pressed "Cancel"
}


更新

据我所知;这不能使用
setTimeout()
setInterval()
来完成,因为这些函数异步执行给定给它们的代码。

confirm()
提示符()
警报()
是特殊的函数——它们从JavaScript沙盒调用到浏览器中,浏览器会暂停JavaScript的执行。您不能做同样的事情,因为您需要将功能构建到JavaScript中

我认为,如果不按照以下思路进行重组,就没有很好的替代方法:

myconfirmfunction(function() {
   /* OK callback */
}, function() {
   /* cancel callback */
});

通常停止执行的方式不应该是无限while循环

将您的工作分解为使用SetTimeout调用的部分

更改此项:

  DoSomeWork();
  Wait(1000);
  var a = DoSomeMoreWork();
  Wait(1000);
  DoEvenMoreWork(a);
为此:

 DoSomeWork();
 setTimeout(function() {
    var a = DoSomeMoreWork();
    setTimeout(function() { 
        DoEvenMoreWork(a);
    }, 1000);
 }, 1000);

您无法在JavaScript中停止事件线程,因此必须解决此问题,通常使用回调函数。这些函数将在以后运行,但可以像JavaScript中的任何其他对象一样传递。您可能对AJAX编程很熟悉。例如:

doSomeThing();
var result = confirm("some importart question");
doSomeThingElse(result);
将转换为:

doSomeThing();
customConfirm("some importart question", function(result){
  doSomeThingElse(result);
});

其中
customConfirm
现在接受一个问题,并将结果传递给作为参数的函数。如果使用按钮实现DOM对话框,则将事件侦听器连接到“确定”和“取消”按钮,并在用户单击其中一个按钮时调用回调函数。

我认为没有任何方法可以在您自己的JavaScript中合理地重新创建confirm()或prompt()的功能。它们是“特殊”的,因为它们被实现为对本机浏览器库的调用。在JavaScript中,您无法真正实现这种模式对话框

我见过各种UI库,它们通过在页面顶部放置一个元素来模拟这种效果,该元素看起来和行为类似于一个模态对话框,但它们是使用异步回调实现的


您必须修改现有库,而不是替换窗口。请确认。

使用回调或使代码仅为Firefox。在支持JavaScript 1.7及更高版本的Firefox中,您可以使用yield语句来模拟所需的效果。我为此创建了一个库,名为。async.js的标准库包括一个确认方法,可以这样使用:

if (yield to.confirm("...")) {
  // user pressed OK
} else {
  // user pressed Cancel
}

我试着用紧循环来解决这个问题。我需要减慢本机事件的速度(AFAIK是无法异步重新构建的同步等待的唯一用例)。有很多示例循环声称不会锁定浏览器;但是没有一个对我有用(浏览器没有锁定,但他们阻止它做我一开始就在等待的事情),所以我放弃了这个想法

接下来,我尝试存储和重放事件,这在跨浏览器中似乎也是不可能的。然而,取决于活动和你需要的灵活性,你可以接近


最后我放弃了,感觉好多了;我找到了一种方法,可以让我的代码工作,而不必降低本地事件的速度。

JavaScript语言有一个扩展名为StratifiedJS。它可以在每个浏览器中运行,并且允许您执行以下操作:停止一行JavaScript代码而不冻结浏览器

您可以启用分层JavaScript,例如在网页中包含Oni Apollo(),如:

<script src="http://code.onilabs.com/latest/oni-apollo.js"></script>
<script type="text/sjs"> your StratifiedJS code here </script>

setTimeout
setInterval
不异步执行代码,它们倒计时,然后将回调函数添加到队列中,当线程空闲时调用该队列。然后函数本身同步运行。另请参见:@Andy E-
window.setTimeout
(和
window.setInterval
)创建异步回调。正常的程序流在调用后立即继续,回调将在稍后的日期执行,具体取决于计时器的长度。JavaScript是单线程的,回调一旦开始执行,就会阻止其他代码执行,这一事实并不妨碍它是异步的。
var dom = require("dom");
displayYourHtmlDialog();
waitfor {
  dom.waitforEvent("okbutton", "click");
  // do something when the user pressed OK
}
or {
  dom.waitforEvent("cancelbutton", "click");
}
hideYourHtmlDialog();
// go on with your application