【问题标题】:While true difference between browser and a compiled program on the OS虽然浏览器和操作系统上的编译程序之间的真正区别
【发布时间】:2015-03-21 22:15:11
【问题描述】:

今天我在他的 Raspberry Pi 上观看了我的一位同事用 Python 编写的一个小游戏。游戏引擎使用while(true) 或无限循环运行。我自己在 PHP 中使用了一个使用 while(true) 的 websocket 程序。在这些示例中,使用了无限 while 循环,它不会导致程序无响应。没有它,它将无法正常工作。然而,在 JavaScript 中,我们需要不惜一切代价避免无限循环。当循环变得无限时,浏览器会挂起并变得无响应。

我的问题:在编译的Python程序中运行的无限循环和用编写的无限循环有什么区别JavaScript 在浏览器中运行?

【问题讨论】:

  • 没有。都阻塞了当前线程。
  • @Haketo 然后 python 循环可能会更新 UI,JS-Code 不会调用浏览器的渲染命令。
  • @Sebb 你的意思是重新绘制?,因为如果在 python 中你没有控制 UI 它应该是相同的结果
  • @Haketo 在某种程度上。当你制作一个游戏时,你通常把它放在一个循环中,第一次调用进入游戏逻辑来更新位置、玩家健康、猫数等等。之后,您调用渲染方法,以便将更新的内容作为图片处理并发送到屏幕。然后你重新开始。在 JavaScript 中,您省略了对渲染函数的调用,因此浏览器的 UI 永远不会更新。
  • Python 可以让你编写多线程代码不是吗? JavaScript 没有(通过网络工作者除外)。

标签: javascript while-loop infinite-loop


【解决方案1】:

不同之处在于 JavaScript 在浏览器的 UI 线程上运行(防止它发送正常的 OS 消息,如绘画),而 Python 程序没有 UI,因此主线程是否是无关紧要的被你的代码占用了。

无论哪种方式,您仍然阻塞主线程,但在不同的上下文中。

【讨论】:

    【解决方案2】:

    Python 和 JavaScript 代码之间的主要区别在于 Python 代码负责更新 UI,而 JS 代码只是循环它的游戏逻辑,因此阻止浏览器更新它的视图。

    当您制作游戏时,您通常会将您的第一次调用转到游戏逻辑以更新位置、玩家健康状况、猫数等类似内容的循环。之后,您调用渲染方法,以便将更新的内容作为图片处理并发送到屏幕。然后你重新开始。在 JavaScript 中,您省略了对渲染函数的调用,因此浏览器的 UI 永远不会更新。

    这与线程无关,但在像 Pyhton(和许多其他语言)这样的语言中,您可以将游戏逻辑和渲染分开,这样当您的逻辑需要一段时间才能完成时,它仍然可以重新定位程序更新您的屏幕(一遍又一遍地使用相同的、未更新的内容,但这是另一个主题)。

    TL;DR JavaScript 会阻塞浏览器的渲染过程,而 Python 循环会显式调用其 UI 的渲染函数。

    对于 JS,您应该使用 setInterval(function, time),正如 @RúnarBerg 指出的那样。

    编辑:@mouser 指出您也可以使用web workers,这似乎是 JS 中多线程的 html5 方法。如果您正在使用 JS 开发游戏,可能值得一看,尤其是因为根据 w3schools,所有主流浏览器都支持它。

    【讨论】:

    • 解释得很清楚。我看到了 webworker 这个词。这可能是一种解决方法吗?
    • @Mouser 这似乎是一个很好的解决方案,具有良好的浏览器支持。我从未真正研究过它,但我会更新答案:)
    【解决方案3】:

    在 Python 中,您的循环可能如下所示:

    while true:
        TakeInput()
        DoStuff()
    

    所以循环的每次迭代都会做一些事情,并且会一直做下去。

    在 JavaScript 中,输入通常来自浏览器。如果您的 JavaScript 代码永远循环,则浏览器永远不会有机会让您的代码知道新的输入已经到达。

    你可以这样写 JavaScript 代码:

    while (true) {
        x = input('Give me input!');
        // Process x
        alert(result);
    }
    

    这将近似于 Python 代码,但这不是 JavaScript 通常的工作方式,并且完全避开了浏览器。

    【讨论】:

      【解决方案4】:

      Javascript 具有异步运行时,这意味着您的代码通常不必等待其他部分继续执行。您可以使用setInterval(fn, time) 运行无限非阻塞循环,它以time 毫秒的间隔执行函数fn

      【讨论】:

      • 这是一个解决方案,但我认为他正在寻找解释。
      • @Sebb 确实。我知道如何通过设置一个非常短的计时器来模拟浏览器中的无限循环。我想更深入地了解浏览器中的无限循环和非浏览器程序之间的区别。
      猜你喜欢
      • 2018-09-22
      • 1970-01-01
      • 2016-06-13
      • 1970-01-01
      • 1970-01-01
      • 2018-05-12
      • 1970-01-01
      • 2011-01-09
      • 1970-01-01
      相关资源
      最近更新 更多