11

请记住,我以前从未使用过 Web Workers,而且我在理解它们时遇到了一些麻烦。

这是我正在做的简化版本的解释。

我的页面有各种文件的链接——有些是文本,有些是图像等。每个文件都有一个显示通用文件图标的图像。

我希望脚本用文件内容的预览替换每个通用图标。

该脚本将从服务器请求文件(从而将其添加到缓存中,如预加载器),然后创建画布并在其上绘制预览(图像缩略图,文本文件的文本摘录,更具体的图标对于媒体文件...),最后使用数据 URL 将通用图标的源替换为画布。

我可以很容易地做到这一点。但是,我更愿意将它放在后台,这样它在工作时就不会干扰 UI。

在我深入研究之前,我需要知道:Workers 可以使用画布,如果可以,我将如何创建一个?我认为document.createElement('canvas')这行不通,因为工人无法访问 DOM,或者当我找到的所有引用都说他们“无法访问 DOM”时我误解了?

4

3 回答 3

10

您无法从 Web Worker 访问 DOM。您无法加载图像。您不能创建画布元素并从网络工作者那里绘制它们。目前,网络工作者几乎仅限于进行 ajax 调用和计算密集型的事情。请参阅有关网络工作者和画布对象的相关问题/答案:网络工作者和画布以及有关使用网络工作者加速图像处理的文章:http: //blogs.msdn.com/b/eternalcoding/archive/2012/09/20 /using-web-workers-to-improve-performance-of-image-manipulation.aspx

你最简单的选择是将你的工作分成小块(没有网络工作者),一次做一个块,做一个setTimeout(),然后处理下一个工作块。这将允许 UI 在完成工作的同时做出响应。如果要完成任何消耗 CPU 的计算(例如进行图像分析),则可以将其外包给 Web Worker,并且可以通过消息将结果发送回主线程以放入 DOM,但如果没有,然后只需将您的工作分成较小的块来保持 UI 的活力。

部分任务,如加载图像、从服务器获取数据等......也可以异步完成,因此如果正确完成,它不会干扰 UI 的响应性。

以下是分块的一般概念:

function doMyWork() {
    // state variables
    // initialize state
    var x, y, z;

    function doChunk() {
        // do a chunk of work
        // updating state variables to represent how much you've done or what remains

        if (more work to do) {
            // schedule the next chunk
            setTimeout(doChunk, 1);
        }

    }
    // start the whole process
    doChunk();
}
于 2013-02-09T07:00:16.353 回答
2

Web Workers 的另一个(令人沮丧的)限制是它无法在 Chrome 上访问地理位置。只是我的两分钱。

于 2017-03-26T03:39:31.723 回答
2

因此,正如其他人所说,您无法访问 DOM,也无法从 Web Worker 对 DOM 进行任何操作。但是,您可以在 web worker 上外包一些更完整的计算。然后,一旦您从主 JS 线程内的 web worker 获得返回消息,您就可以提取所需的值并在那里的 DOM 上使用它们。

这可能与您的问题无关,但您提到了画布,所以我将与您分享。

如果您需要提高绘制到画布的性能,我强烈建议您使用两个画布对象。一个渲染到 UI,另一个隐藏。这样您就可以在隐藏的画布上构建所有内容,然后在显示的画布上绘制隐藏的画布。听起来可能没什么用,但它会显着提高性能。

有关提高画布性能的更多详细信息,请参阅此链接

于 2019-03-28T19:28:37.983 回答