【发布时间】:2020-03-31 21:33:38
【问题描述】:
我正在尝试将 self.setTimeout() 函数包装在网络工作者中(因此没有本机窗口对象)。我认为使用方法 apply 语法会非常简单:
window.setTimeout = function ( /**/) {
return setTimeout.apply(self,arguments);
};
这个调用应该等同于使用任意数量的参数(函数、延迟、传递给函数的参数)调用 self.setTimeout() 并返回超时的 id。
但是,中间的代码行最终会抛出“递归过多”的错误。看起来像这样调用它以某种方式破坏了此处描述的机制:Will a recursive 'setTimeout' function call eventually kill the JS Engine? 破坏了先前的函数上下文并使其实际上是递归的。以防它是特定于浏览器的:在 Firefox 74.0(64 位)中测试。
一些背景
以防万一有人想知道,我为什么要这样做:
我想在不重写所有内容的情况下将一些 CPU 密集型代码从主线程转移到 web-workers。
不幸的是,代码依赖于一些库,而这些库又依赖于存在的窗口和文档,否则它不会初始化。
作为一种解决方法,我在工作人员内部使用Mock Dom。因为我实际上并不想进行 DOM 操作,所以我只是以最简单的方式添加模拟 dom 中缺少的任何功能。但出于某种原因,库有时会显式调用 window.setTimeout() 而不仅仅是 setTimeout() - 所以我需要将此函数添加到模拟窗口对象中,并且它需要正常工作。
更新
谢谢,Alexandre Senges 指出了这个函数实际上会调用自己的错误。
在 web-Worker 中实际可行的解决方案是
window.setTimeout = function ( /**/) {
return DedicatedWorkerGlobalScope.prototype.setTimeout.apply(self,arguments);
};
所以,我需要编写函数的整个路径,以防止 window.setTimeout 调用自身。
更新 2
实际上,正如 Kaiido 的另一个回答所指出的那样,我最初的想法本身应该可以正常工作。发生过多递归的原因是我在有效复制self.setTimeout = window.setTimeout的代码的其他部分出错 - 从而导致setTimeout===self.setTimeout===window.setTimeout 因此函数window.setTimeout突然无意识地递归。
【问题讨论】:
标签: javascript web-worker