Related free learning recommendations: javascript (video)
This time we will step by step To explain Web Workers, start with a simple concept, and then discuss different types of Web Workers and how their components work together work, and their respective advantages and limitations in different scenarios. Finally, provide 5 scenarios for the correct use of Web Workers.
As we discussed in the previous article, you should know that the JavaScript language uses a single-threaded model. However, JavaScript also provides developers with the opportunity to write asynchronous code.
Previous articles have discussed asynchronous programming and when you should use it.
Asynchronous programming can make the UI interface responsive (fast rendering speed). Through "code scheduling", the code that needs to request time is first placed in the event loop and then executed later, thus allowing the UI to Render display first.
A good use case for asynchronous programming is AJAX requests. Since requests can take a lot of time, you can use asynchronous requests, which allow other code to execute while the client is waiting for a response.
However, this brings up a problem - the request is handled by the browser's WEB API, but how to make other code asynchronous? For example, if it succeeds The code in the callback is very CPU intensive:
var result = performCPUIntensiveCalculation();
If performCPUIntensiveCalculation
is not an HTTP request but a blocking code (such as a for loop with a lot of content), there is no way to clear the event loop in time , the browser's UI rendering will be blocked, and the page cannot respond to the user in time.
This means that asynchronous functions can only solve a small part of the limitations of the single-threaded JavaScript language.
In some cases, you can use setTimeout
to block long-running calculations. You can use setTimeout
to temporarily put it into the asynchronous queue to get the page. Faster rendering. For example, by batching complex calculations in separate setTimeout
calls, you can put them in separate "spots" in the event loop, which can strive for UI rendering/response execution time.
Look at a simple function that calculates the average of an array of numbers:
Here’s how to rewrite the above code and “simulate” asynchronicity:
function averageAsync(numbers, callback) { var len = numbers.length, sum = 0; if (len === 0) { return 0; } function calculateSumAsync(i) { if (i <p>Use the setTimeout function which will add each step of the calculation further in the event loop. Between each calculation, there will be enough time for other calculations to occur, allowing the browser to render. </p><h2>Web Worker can solve this problem</h2><p>HTML5 brings us a lot of new things, including:</p>
The role of Web Worker is to create a multi-threaded environment for JavaScript, allowing the main thread to create Worker threads and assign some tasks to the latter for execution. . While the main thread is running, the Worker thread is running in the background, and the two do not interfere with each other. Wait until the Worker thread completes the calculation task, and then returns the result to the main thread. The advantage of this is that some computing-intensive or high-latency tasks are burdened by the Worker thread, and the main thread (usually responsible for UI interaction) will be smooth and will not be blocked or slowed down.
You may ask: "Isn't JavaScript a single-threaded language?"
In fact, JavaScript is a language that does not define a threading model. Web Workers are not part of JavaScript, but are browser features accessible through JavaScript. Historically, most browsers were single-threaded (of course, this has changed) and most JavaScript implementation occurred in the browser. Web Workers are not implemented in Node.JS. There are similar concepts of cluster and child_process in Node.js. They are also multi-threaded but are still different from Web Workers.
It is worth noting that there are three types of Web Workers mentioned in the specification:
Dedicated Workers can only be accessed by the page that created them, and can only communicate with it. The following is what browsers support:
共享 Workers 在同一源(origin)下面的各种进程都可以访问它,包括:iframes、浏览器中的不同tab页(一个tab页就是一个单独的进程,所以Shared Workers可以用来实现 tab 页之间的交流)、以及其他的共享 Workers。以下是浏览器支持的情况:
Service Worker 功能:
在目前阶段,Service Worker 的主要能力集中在网络代理和离线缓存上。具体的实现上,可以理解为 Service Worker 是一个能在网页关闭时仍然运行的 Web Worker。以下是浏览器支持的情况:
本文主要讨论 专用 Workers,没有特别声明的话,Web Workers、Workers都是指代的专用 Workers。
Web Workers 一般通过脚本为 .js
文件来构建,在页面中还通过了一些异步的 HTTP 请求,这些请求是完全被隐藏了的,你只需要调用 Web Worker API.
Worker 利用类线程间消息传递来实现并行性。它们保证界面的实时性、高性能和响应性呈现给用户。
Web Workers 在浏览器中的一个独立线程中运行。因此,它们执行的代码需要包含在一个单独的文件中。这一点很重要,请记住!
让我们看看基本 Workers 是如何创建的:
var worker = new Worker('task.js');
Worker()
构造函数的参数是一个脚本文件,该文件就是 Worker 线程所要执行的任务。由于 Worker 不能读取本地文件,所以这个脚本必须来自网络。如果下载没有成功(比如404错误),Worker 就会默默地失败。
为了启动创建的 Worker,需要调用 postMessage
方法:
worker.postMessage();
为了在 Web Worker 和创建它的页面之间进行通信,需要使用 postMessage
方法或 Broadcast Channel。
新浏览器支持JSON对象作为方法的第一个参数,而旧浏览器只支持字符串。
来看一个示例,通过将 JSON 对象作为一个更“复杂”的示例传递,创建 Worker 的页面如何与之通信。传递字符串跟传递对象的方式也是一样的。
让我们来看看下面的 HTML 页面(或者更准确地说是它的一部分):
<button>Start computation</button> <script> function startComputation() { worker.postMessage({'cmd': 'average', 'data': [1, 2, 3, 4]}); } var worker = new Worker('doWork.js'); worker.addEventListener('message', function(e) { console.log(e.data); }, false); </script>
然后这是 worker 中的 js 代码:
self.addEventListener('message', function(e) { var data = e.data; switch (data.cmd) { case 'average': var result = calculateAverage(data); // 从数值数组中计算平均值的函数 self.postMessage(result); break; default: self.postMessage('Unknown command'); } }, false);
当单击该按钮时,将从主页调用 postMessage
。postMessage 行将 JSON 对象传给Worker。Worker 通过定义的消息处理程序监听并处理该消息。
当消息到达时,实际的计算在worker中执行,而不会阻塞事件循环。Worker 检查传递的事件参数 e
,像执行 JavaScript 函数一样,处理完成后,把结果传回给主页。
在 Worker 作用域中,this 和 self 都指向 Worker 的全局作用域。
有两种方法可以停止 Worker:从主页调用worker.terminate()
或在worker
内部调用self.close()
。
Broadcast Channel API 允许同一原始域和用户代理下的所有窗口,iFrames 等进行交互。也就是说,如果用户打开了同一个网站的的两个标签窗口,如果网站内容发生了变化,那么两个窗口会同时得到更新通知。
还是不明白?就拿 Facebook 作为例子吧,假如你现在已经打开 了Facebook 的一个窗口,但是你此时还没有登录,此时你又打开另外一个窗口进行登录,那么你就可以通知其他窗口/标签页去告诉它们一个用户已经登录了并请求它们进行相应的页面更新。
// Connection to a broadcast channel var bc = new BroadcastChannel('test_channel'); // Example of sending of a simple message bc.postMessage('This is a test message.'); // Example of a simple event handler that only // logs the message to the console bc.onmessage = function (e) { console.log(e.data); } // Disconnect the channel bc.close()
可以从下面这张图,在视觉上来清晰地感受 Broadcast Channel:
Broadcast Channel 浏览器支持比较有限:
有两种方式发送消息给Web Workers:
Due to the multi-threaded nature of JavaScript, Web Workers can only access a subset of JavaScript features. Here are some of its features:
Web Workers can only access a subset of JavaScript features due to their multi-threaded nature. The following is a list of available properties:
importScripts()
Import external scriptsUnfortunately, Web Workers do not have access to some very critical JavaScript features:
This means that the Web Worker cannot manipulate the DOM (and therefore the UI ). This can be tricky at times, but once you understand how to use Web Workers correctly, you'll start using them as separate "computers" and all UI changes will happen in your page code. Workers will do all the heavy lifting for you and then return the results to the page once complete.
Just like JavaScript code, you also need to handle errors thrown by Web workers. If an error is encountered during Worker execution, an ErrorEvent
event will be triggered. The interface contains three useful properties to help troubleshoot problems:
Examples are as follows:
In Here, you can see that we created a worker and started listening for error events.
Inside the worker (in workerWithError.js
) we create an exception by multiplying undefinedx
by 2 . The exception is propagated to the initial script, and then the error event is monitored through the page to capture the error.
So far, we have listed the advantages and limitations of Web Workers. Now let’s see what their most powerful use cases are:
Spell checking: The workflow of a basic spell checking program is as follows - the program reads a dictionary file with a list of correctly spelled words. The dictionary is parsed into a search tree to make actual text searches more efficient. When a word is provided to the checker, the program checks whether it exists in a pre-built search tree. If the word is not found in the tree, you can provide the user with an alternative spelling by substituting the replacement character and testing whether it is a valid word if it is the word the user wanted to write. All these processes can be carried out in the Web Worker. Users can enter words and sentences without being blocked. The Web Worker checks whether the words are correct in the background and provides alternative words.
If you want to learn more about programming, please pay attention to the php training column!
The above is the detailed content of The building blocks of JavaScript Web Workers and 5 usage scenarios. For more information, please follow other related articles on the PHP Chinese website!