【问题标题】:How to run javascript function in web browser only when is not proccesing that function仅在不处理该功能时如何在 Web 浏览器中运行 javascript 功能
【发布时间】:2015-05-22 14:31:31
【问题描述】:

我的一个 javascript 函数正在处理数百万个数据,它在硬件事件中每秒被调用约 1 次。然后网络浏览器在该函数处理中处于空闲状态。

我试图为运行(或不运行)该功能设置一个标志:

if (!is_calculating)
    is_calculating = true;
else
    return;


my_function(); // do heavy stuff


is_calculating = false;

但它不起作用,因为它正在输入代码并且网络浏览器进入空闲状态,直到完成。当它返回时,标志总是 OK,因为它完成了 // 做繁重的事情

我可以为这种行为做些什么吗?如果设置了标志,我想跳转函数执行。

【问题讨论】:

  • 您的问题不清楚。您的函数究竟是如何调用“~1 time per second”的?
  • 我很抱歉。我更改了代码。它由移动 GPS 事件调用。
  • 你在问如何异步调用你的函数
  • 您是否试图避免浏览器 UI 因计算繁重而挂起和冻结?

标签: javascript performance cross-browser


【解决方案1】:

问题在于,默认情况下,javascript 在浏览器上的单线程中运行,因此您的代码甚至在开始处理下一次调用之前就已完全执行,导致在调用函数时is_calculating 始终为 false。您可以使用的一种解决方法(不是世界上最干净的解决方案)是将您的整体“繁重的东西”功能划分为多个较小的功能,并让它们使用setTimeout(nextFunc, 1) 相互调用。让它们以这种方式互相调用可以让浏览器有时间去做它需要做的事情,如果它正在做的话,还可以再次调用你的函数。这一次,因为你的函数是在它已经被执行的“中间”被调用的,is_calculating 仍然是真的,并且调用会像你期望的那样在开始时返回。请注意,此解决方案可能不如Web Workers solution 可取,但更简单。

function sleep(millis) {
  var date = new Date()
  var curDate = null
  do { curDate = new Date() }
  while(curDate-date < millis)
}

function reallyLong() {
  if(!reallyLong.flag) {
    reallyLong.flag = true
  } else {
    console.log("Not executing")
    return
  }

  sleep(250)
  setTimeout(reallyLong2, 1)

  function reallyLong2() {
    sleep(250)
    setTimeout(reallyLong3, 1)
  }

  function reallyLong3() {
    sleep(250)
    setTimeout(reallyLong4, 1)
  }

  function reallyLong4() {
    sleep(250)
    console.log("executed")
    reallyLong.flag = false
  }
}

如果您在主函数中定义所有连续函数,它还允许它们都简单轻松地访问相同的数据。

现在唯一的问题是,如果您的函数返回某个值,您需要重写它以返回 promise(您自己的设计或使用像 Q 这样的库),或者接受回调作为'chain' 中的最后一个函数将以返回值作为参数调用的参数。

请注意,上面的 sleep 函数是一个 hack,非常糟糕,非常糟糕,永远不应该使用。

【讨论】:

  • 非常感谢!我会考虑这个解决方案;)
【解决方案2】:

默认情况下,浏览器中的 JavaScript 执行不是并发的。这意味着,通常只有一个当前正在执行的代码。

你必须使用Web Workers API 让你的代码同时运行。

【讨论】:

    猜你喜欢
    • 2021-10-06
    • 1970-01-01
    • 2012-09-22
    • 2020-07-28
    • 2019-02-22
    • 2021-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多