代码之家  ›  专栏  ›  技术社区  ›  cllpse

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

  •  6
  • cllpse  · 技术社区  · 15 年前

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

    你对这个有什么看法?


    我想超越 window.confirm() 使用HTML实现我自己的对话框。我这样做是为了不必更改现有代码(这是一个相当大的代码库)。

    我需要能够停止执行以允许用户输入;然后返回一个布尔值,就像标准确认函数那样:

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



    更新

    据我所知,这不能用 setTimeout() setInterval() 因为这些函数执行异步提供给它们的代码。

    7 回复  |  直到 11 年前
        1
  •  9
  •   Ben Zotto sberry    14 年前

    confirm() prompt() alert() 是特殊的函数——它们从JavaScript沙盒中调用到浏览器中,浏览器挂起JavaScript的执行。您不能做同样的事情,因为您需要将您的功能构建到JavaScript中。

    我认为,如果不按照以下原则进行一些重组,就没有一个很好的方法来替换:

    myconfirmfunction(function() {
       /* OK callback */
    }, function() {
       /* cancel callback */
    });
    
        2
  •  7
  •   Eli Grey    15 年前

    要么使用回调,要么只使用代码firefox。在支持javascript 1.7及更高版本的Firefox中,您可以使用yield语句来模拟您想要的效果。我创建了一个图书馆 async.js . async.js的标准库包括一个confirm方法,可以这样使用:

    if (yield to.confirm("...")) {
      // user pressed OK
    } else {
      // user pressed Cancel
    }
    
        3
  •  7
  •   Marius    12 年前

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

    doSomeThing();
    var result = confirm("some importart question");
    doSomeThingElse(result);
    

    将转换为:

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

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

        4
  •  3
  •   tomg    14 年前

    Javascript语言有一个扩展名为Stratediedj。它在每个浏览器中运行,它允许您这样做:停止一行JavaScript代码而不冻结浏览器。

    您可以启用分层的javascript,例如通过包括oni apollo( http://onilabs.com/docs )在你的网页上,比如:

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

    您的代码如下所示:

    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
    
        5
  •  2
  •   Jimmy    15 年前

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

    把你的工作分成几个部分,用SETTIMEOUT调用它们

    改变这一点:

      DoSomeWork();
      Wait(1000);
      var a = DoSomeMoreWork();
      Wait(1000);
      DoEvenMoreWork(a);
    

    对此:

     DoSomeWork();
     setTimeout(function() {
        var a = DoSomeMoreWork();
        setTimeout(function() { 
            DoEvenMoreWork(a);
        }, 1000);
     }, 1000);
    
        6
  •  1
  •   Mark Bessey    15 年前

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

    我看到过各种各样的UI库,它们通过将元素放在页面顶部来模拟效果,这些库看起来和模式对话框类似,但它们是使用异步回调实现的。

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

        7
  •  0
  •   Community dbr    7 年前

    我试着用紧环 this . 我需要降低本地事件的速度(对于不能异步重新架构的同步等待,Afaik是唯一的用例)。有很多循环例子声称不锁定浏览器,但是没有一个对我有用(浏览器没有锁定,但是他们阻止它做我一开始等待的事情),所以我放弃了这个想法。

    接下来我尝试 this -存储和重放事件,这似乎也不可能跨浏览器进行。然而,根据事件和您需要的灵活性,您可以接近。

    最后,我放弃了,感觉好多了;我找到了一种方法让我的代码工作起来,而不必放慢原生事件的速度。