【问题标题】:Javascript function stops executing when another interaction occurs当发生另一个交互时,Javascript 函数停止执行
【发布时间】:2019-06-24 17:27:41
【问题描述】:

在下面的代码示例中,我有两个按钮可以执行以下操作:

1) 点击按钮 1 执行 while 循环

2) 点击按钮2执行日志语句

如果单击按钮 1,然后单击按钮 2,按钮 1 将停止执行。

当另一个动作发生时是否可以让按钮 1 继续执行?

function buttonOneClick() {
  let i = 0;
  while (i < 1000) {
    console.log('index is ', i);
    i++;
  }
}

function buttonTwoClick() {
  console.log('button two clicked');
}
<button type="button" onclick="buttonOneClick()">Click Button One and Start Loop</button>
<button type="button" onclick="buttonTwoClick()">Click Button Two</button>

【问题讨论】:

  • 我没有看到你描述的行为,但答案是“不”; JavaScript 是单线程的。在浏览器响应单击另一个按钮之前,按钮 1 处理程序中的代码将继续运行所有 1000 次迭代。
  • 我怀疑您的实际代码取决于 console.log 调用。实际的问题代码是什么?
  • @Pointy 如果您运行代码 sn-p 并单击按钮一,您应该会看到索引开始记录。如果您单击按钮 2,您将看到索引停止被记录,并且“按钮 2 单击”被记录。
  • 我确实这样做了,但它对我 (Firefox) 不起作用。如果您在 Chrome 中看到这种情况,那是因为 Chrome 中的 console 机制很奇怪。
  • 如果我理解了,您想知道为什么当用户离开页面时代码会停止?

标签: javascript html


【解决方案1】:

“JavaScript 多线程”的解决方案:您可以使用 webworkers 来解决这个问题。将您要执行的代码放在后台运行的 webworker 中(根据定义):

Web Workers 是一种让 Web 内容在其中运行脚本的简单方法 后台线程。工作线程无需执行任务即可 干扰用户界面。此外,它们还可以执行 I/O 使用 XMLHttpRequest(虽然 responseXML 和 channel 属性 始终为空)。创建后,worker 可以向 通过向事件发布消息来创建它的 JavaScript 代码 该代码指定的处理程序(反之亦然)。

https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

使用此解决方案,您可以连续执行您的功能,并且仍然可以访问其他功能。

请注意,这不是我的解决方案中的传统网络工作者,而是内联网络工作者

function buttonOneClick() {
  // create an inline webworker
  var blob = new Blob([
    document.querySelector('#worker1').textContent
  ], {
    type: "text/javascript"
  })

  // Note: window.webkitURL.createObjectURL() in Chrome 10+.
  var worker = new Worker(window.URL.createObjectURL(blob));
  worker.onmessage = function(e) {
    console.log("Received: " + e.data);
  }
  worker.postMessage("hello"); // Start the worker.
}

function buttonTwoClick() {
  console.log('button two clicked');
}
<button type="button" onclick="buttonOneClick()">Click Button One and Start Loop</button>
<button type="button" onclick="buttonTwoClick()">Click Button Two</button>

<script id="worker1" type="javascript/worker">
  // This script won't be parsed by JS engines because its type is javascript/worker.
  self.onmessage = function(e) {
    for (let i = 0; i < 1000; i++) {
      self.postMessage( 'message from worker ' + i)
    }
  };
// Rest of your worker code goes here.
</script>

要检查结果,请使用真正的控制台,然后向后滚动一些 - 你会找到你的 buttonTwoClick() console.log()

一个注释,不过

不要在 sn-p 中按 Tidy - 它会弄乱工作人员,因为它无法“理解”那是什么。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-24
    • 2021-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-01
    • 1970-01-01
    相关资源
    最近更新 更多