全文共2548字,预计学习时长8分钟
来源:Pexels
多年以来,JavaScript最麻烦的特征之一就是,如果某个任务耗时太长,剩下的代码就会遇到阻塞而无法运行。
JavaScript是单线程的编程语言,这一特点导致用户需要等待代码按照顺序运行。
但事实上有一种方式可以避免这种困境,它就是Worker。
在本文中,小芯将介绍Worker的使用方式。
阅读之前读者需要知道JavaScript是一种单线程语言。
同步编码先来看看读者可能已经熟知的JavaScript代码样式
let cnt = 0;for (let i = 0; i < 10e8; i += 1) { cnt += 1;}console.log(cnt);
在这段代码的for循环中,cnt每次增加1,总共增加了次。而console.log要等到for循环结束后才能执行。
在Chrome浏览器控制台中,这需要花费很长时间。
这段代码需要耗费将近3秒。
无论如何,直到for循环结束cnt才会打印出来。
许多开发者都被这个问题困扰,因为用户必须等待当前执行的任务完成。
异步代码来源:Pexels
JavaScript的设计者为开发者提供了不会阻塞程序流的特殊函数。这些函数处于和普通任务不同的等待队列中。一般而言,它们可以在所有普通程序执行之后再执行。这些任务被称为异步任务。
let cnt = 0;tTimeout(() => { for (let i = 0; i < 10e8; i += 1) { cnt += 1; } console.log(cnt);});console.log(cnt);
这段代码的运行结果和前面一段有所不同。
但仍然需要等待较长的时间。
这里的for循环包含在 tTimeout中. tTimeout中的代码会等待所有普通任务完成后再执行。
但这并非解决代码流堵塞问题的最佳方案。虽然 tTimeout是一个不阻碍正常代码流的异步函数,但是这样做仅仅改变了函数的执行顺序。
let cnt = 0;tTimeout(() => { for (let i = 0; i < 10e8; i += 1) { cnt += 1; } console.log(cnt);});tTimeout(() => { console.log(cnt);});console.log(cnt);
看看这个例子,其中使用了另一个tTimeout,它包含一个立即打印cnt的函数。然而第二个tTimeout总是在第一个tTimeout结束for循环后才开始运行console.log(cnt)指令。如果第一个tTimeout包含的任务耗时较长,那么第二个tTimeout将无法运行。
为什么?因为Javascript是一种单线程编程语言。异步函数存在于不同的任务队列中,但它们仍然遵循单线程规则。
WorkersWeb Worker是一种网络接口,这意味着它无法访问或管理文档对象模型。Worker存在于一个不同的线程中,它和主线程互不干扰。它在一个新的Worker对象创建时接受信息,然后向worker发送信息。
let worker;if ('Worker' in window) { worker = new Worker('file_name');}
创建新的Worker实例十分简单。new Worker这条指令接受一个字符串或者超链接作为参数。这个参数的格式一般如下所示:
new Worker('/worker.js');
实例创建之后,可以向另一个线程发送信息。
worker.postMessage('From Main Thread');
于是可以在worker所处的线程中收到这个信息。
// worker.jsthis.addEventListener('message', event => { console.log(event.data);});
Worker成功接受信息。
如果仔细查看日志,会发现文件名是worker.js而不是main.js或者app.js。这说明worker接受了完好的信息。
现在,让worker在收到主线程信息的同时也向主线程发送一条信息。
// main.jsworker.addEventListener('message', event => { console.log(event.data);});// worker.jsthis.addEventListener('message', event => { ... this.postMessage('From Worker Thread');});
这段代码看起来有些冗余。读者将会看到其工作流,但是首先来看看结果。
现在能看到两条信息。
这段代码是如何工作的呢?
onMessage代表从线程另一端接受信息这一事件,postMessage则代表向线程另一端发送信息这一事件。
代码测试在这个测试中可以看到两点。
· For循环的运行总时长
· 代码阻断
这个示例使用React制作。状态消息应该按照预期打印,然而同步和异步行为不会打印除了总运行时长外的任何信息。因为在React中,状态改变也是一种异步行为,需要等待普通任务和其他前序异步任务完成才能执行。
另一方面,worker不需要等待,因为它位于另一个线程中。For循环在worker线程中,异步任务则在主线程中,所以它们不会互相打断。
结论来源:Pexels
通常worker被用于占用大量CPU资源的程序中,比如2D canvas 和矢量图。因为worker位于另一个线程中,它不会阻断主线程中的任何任务,比如UI渲染。如果能将worker运用自如,它的效果将十分强大。包括IE10在内的众多浏览器都能够很好地支持这一功能。
留言点赞关注
我们一起分享AI学习与发展的干货
如转载,请后台留言,遵守转载规范
本文发布于:2023-02-28 20:14:00,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/zhishi/a/167766506882507.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:worker(worker怎么读音发音).doc
本文 PDF 下载地址:worker(worker怎么读音发音).pdf
留言与评论(共有 0 条评论) |