如何仅在不处理该功能时才在 Web 浏览器中 运行 javascript 功能

How to run javascript function in web browser only when is not proccesing that function

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

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

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


my_function(); // do heavy stuff


is_calculating = false;

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

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

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

您必须使用 Web Workers API 才能同时编码 运行。

问题是,默认情况下 javascript 在浏览器上以单线程运行,因此您的代码甚至在开始处理下一个调用之前就已完全执行,导致 is_calculating 始终为 false当函数被调用时。您可以使用的一种解决方法(不是世界上最干净的解决方案)是将整体 'heavy stuff' 函数分成许多较小的函数,并让它们通过 setTimeout(nextFunc, 1) 相互调用。让它们以这种方式相互调用,让浏览器有时间做它需要做的事情,如果它正在做的话,还会再次调用你的函数。这一次,因为你的函数是在它已经被执行的 'middle' 中被调用的,所以 is_calculating 仍然是真的,并且调用将在开始时 return 就像你期望的那样.请注意,此解决方案可能不如 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
  }
}

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

现在唯一的问题是如果你的函数是 returning 一些值,你需要将它重写为 return a promise (Either of your own design or using a library like Q),或者接受回调作为参数'chain' 中的最后一个函数将使用 return 值作为参数调用。

请注意,上面的 sleep 函数是 hack,非常糟糕,绝对不应该使用。