Web Workers
의 올바른 사용을 위한 5가지 시나리오를 제공합니다. 비동기 프로그래밍의 한계
이전 기사에서는 비동기 프로그래밍과 이를 사용해야 하는 경우에 대해 논의했습니다. 비동기 프로그래밍은 UI 인터페이스를 반응형(빠른 렌더링)으로 만들 수 있습니다. "코드 스케줄링"을 통해 시간을 요청해야 하는 코드가 이벤트 루프에 배치된 다음 나중에 실행되므로 UI가 먼저 렌더링되고 표시됩니다. 비동기 프로그래밍의 훌륭한 사용 사례는 AJAX 요청입니다. 요청에는 많은 시간이 걸릴 수 있으므로 클라이언트가 응답을 기다리는 동안 다른 코드를 실행할 수 있는 비동기식 요청을 사용할 수 있습니다.
그러나 이로 인해 문제가 발생합니다. 요청은 브라우저의 WEB API에 의해 처리되지만 다른 코드를 비동기식으로 만드는 방법은 무엇입니까? 예를 들어 성공 콜백의 코드가 CPU를 많이 사용하는 경우:var result = performCPUIntensiveCalculation();
performCPUIntensiveCalculation
은 HTTP 요청이 아니라 차단 코드(예: 콘텐츠가 많은 for 루프)이므로 이벤트 루프를 제때 지울 수 없으며 브라우저의 UI 렌더링이 차단되면 페이지가 제때에 사용자에게 응답할 수 없습니다. 이는 비동기 함수가 JavaScript 언어의 단일 스레딩 제한 사항 중 일부만 해결할 수 있음을 의미합니다. 어떤 경우에는 setTimeout
을 사용하여 장기 실행 계산을 차단할 수 있습니다. setTimeout
을 사용하여 일시적으로 비동기 대기열에 넣어 페이지 속도를 높일 수 있습니다. 렌더링의. 예를 들어, 별도의 setTimeout
호출로 복잡한 계산을 일괄 처리하면 이를 이벤트 루프의 별도 "지점"에 배치하여 UI 렌더링/응답성에 대한 실행 시간을 얻을 수 있습니다.
function averageAsync(numbers, callback) { var len = numbers.length, sum = 0; if (len === 0) { return 0; } function calculateSumAsync(i) { if (i <code>performCPUIntensiveCalculation</code> 不是一个HTTP请求而是一个阻塞代码(比如一个内容很多的for loop循环),就没有办法及时清空事件循环,浏览器的 <strong><em>UI</em></strong> 渲染就会被阻塞,页面无法及时响应给用户。<p>这意味着异步函数只能解决一小部分 JavaScript 语言单线程中的局限性问题。</p><p>在某些情况下,可以使用 <code>setTimeout</code> 对长时间运行的计算阻塞的,可以使用 <code>setTimeout</code>暂时放入异步队列中,从让页面得到更快的渲染。例如,通过在单独的 <code>setTimeout</code>이벤트 루프에 포함될 setTimeout 함수를 사용하세요. 계산의 각 단계가 추가됩니다. 각 계산 사이에는 브라우저가 렌더링할 수 있도록 다른 계산이 발생할 수 있는 충분한 시간이 있습니다. <strong></strong>Web Worker는 이 문제를 해결할 수 있습니다. </p><p>HTML5는 다음을 포함하여 많은 새로운 기능을 제공합니다. </p><p><img src="https://img.php.cn/upload/image/761/133/100/1607064795245272.png" title="1607064795245272.png" alt="JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오">SSE(이전 기사에서 WebSocket에 대해 설명하고 비교한 적이 있음) </p><p>Geolocation </p><p>애플리케이션 캐시</p><h2>로컬 저장소 </h2><p>드래그 앤 드롭</p>
Shared Workers(Shared Workers)
Service Workers(서비스 워커)
Dedicated Workers개인 작업자는 해당 작업자를 생성한 페이지에서만 액세스하고 통신할 수 있습니다. 브라우저가 지원하는 사항은 다음과 같습니다.
共享 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:
JavaScript의 다중 스레드 특성으로 인해 Web Worker는 JavaScript 기능의 하위 집합에만 액세스할 수 있습니다. 다음은 그 기능 중 일부입니다.
Web Worker는 다중 스레드 특성으로 인해 JavaScript 기능의 하위 집합에만 액세스할 수 있습니다. 다음은 사용 가능한 기능 목록입니다.
importScripts()
importScripts()
导入外部脚本遗憾的是,Web Workers 无法访问一些非常关键的 JavaScript 特性:
这意味着 Web Worker 不能操作 DOM (因此也不能操作 UI)。有时这可能很棘手,但是一旦你了解了如何正确使用 Web Workers,你就会开始将它们作为单独的“计算机”使用,而所有 UI 更改都将发生在你的页面代码中。 Workers 将为你完成所有繁重的工作,然后一旦完成再把结果返回给 page 页面。
和 JavaScript 代码一样,Web workers 里抛出的错误,你也需要进行处理。当 Worker 执行过程中如果遇到错误,会触发一个 ErrorEvent
事件。接口包含了三个有用的属性来帮忙排查问题:
例子如下:
在这里,可以看到我们创建了一个 worker 并开始侦听错误事件。
在 worker 内部(在 workerWithError.js
中),我们通过将未定义 x
웹 작업자의 제한
🎜안타깝게도 웹 작업자는 몇 가지 매우 중요한 JavaScript 기능에 액세스할 수 없습니다.🎜🎜🎜DOM( 스레드가 안전하지 않게 됩니다)🎜🎜window object🎜🎜document object🎜🎜parent object🎜🎜🎜 이는 Web Worker가 DOM(따라서 UI)을 조작할 수 없음을 의미합니다. 이는 때때로 까다로울 수 있지만 Web Workers를 올바르게 사용하는 방법을 이해하고 나면 이를 별도의 "컴퓨터"로 사용하기 시작하고 모든 UI 변경 사항이 페이지 코드에서 발생합니다. 작업자는 귀하를 위해 모든 힘든 작업을 수행한 다음 완료되면 결과를 페이지에 반환합니다. 🎜🎜오류 처리🎜🎜JavaScript 코드와 마찬가지로 웹 워커에서 발생한 오류도 처리해야 합니다. 작업자 실행 중에 오류가 발생하면ErrorEvent
이벤트가 트리거됩니다. 인터페이스에는 문제 해결에 도움이 되는 세 가지 유용한 속성이 포함되어 있습니다. 🎜🎜🎜🎜filename🎜 - 작업자를 발생시킨 스크립트의 이름 🎜🎜🎜lineno🎜 - 오류가 발생한 줄 번호 🎜🎜🎜 메시지🎜 - 오류 🎜🎜🎜예제는 다음과 같습니다. 🎜🎜🎜 🎜여기서 작업자를 생성하고 오류 이벤트 수신을 시작한 것을 볼 수 있습니다. 🎜🎜 🎜🎜at 작업자 내부(workerWithError.js
)에서 정의되지 않은 x
에 2를 곱하여 예외를 생성합니다. 예외는 초기 스크립트로 전파된 다음 페이지를 통해 오류 이벤트를 모니터링하여 오류를 캡처합니다. 🎜🎜5 Good Web Workers 적용 사례🎜🎜지금까지 Web Worker의 장점과 한계를 나열했습니다. 이제 가장 강력한 사용 사례가 무엇인지 살펴보겠습니다. 🎜맞춤법 검사: 기본 맞춤법 검사기의 작업 흐름은 다음과 같습니다. 프로그램은 철자가 정확한 단어 목록이 포함된 사전 파일을 읽습니다. 사전은 검색 트리로 구문 분석되어 실제 텍스트 검색을 더욱 효율적으로 만듭니다. 검사기에 단어가 제공되면 프로그램은 해당 단어가 미리 작성된 검색 트리에 존재하는지 확인합니다. 해당 단어가 트리에서 발견되지 않으면 대체 문자를 대체하고 사용자가 작성하려는 단어인 경우 유효한 단어인지 테스트하여 사용자에게 대체 철자를 제공할 수 있습니다. 이 모든 과정은 Web Worker에서 수행될 수 있으며, 사용자는 차단 없이 단어와 문장을 입력할 수 있습니다. Web Worker는 백그라운드에서 단어가 올바른지 확인하고 대체 단어를 제공합니다.
프로그래밍에 대해 더 자세히 알고 싶다면 php training 칼럼을 주목해주세요!
위 내용은 JavaScript Web Worker의 구성 요소와 5가지 사용 시나리오의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!