Web Worker는 HTML5에서 제공하는 자바스크립트 멀티스레딩 솔루션입니다. 계산 집약적인 일부 코드를 웹 작업자에게 넘겨 사용자 인터페이스를 중단하지 않고 실행할 수 있습니다.
1: 워커 사용 방법Web Worker의 기본 원리는 Worker 클래스를 사용하여 JavaScript의 현재 메인 스레드에 JavaScript 파일을 로드하여 새 스레드를 여는 것인데, 이는 Non-Blocking 실행 효과가 있으며 메인 스레드 간 데이터 교환을 위한 인터페이스를 제공합니다. 그리고 새로운 스레드: postMessage, onmessage.
그럼 어떻게 사용하는지 예를 살펴보겠습니다.
//worker.jsonmessage =function (evt){ var d = evt.data;//evt.data를 통해 전송된 데이터 가져오기 postMessage(d);//얻은 데이터를 메인 스레드로 전송}HTML 페이지: test.html
<!DOCTYPE HTML><html><head> <meta http-equiv=Content-Type content=text/html/> <script type=text/javascript>//WEB 페이지 메인 스레드 var 작업자 = new Worker(worker.js); //Worker 객체를 생성하고 새 스레드에서 실행될 스크립트의 URL을 전달합니다. Worker.postMessage(hello world) //작업자에게 데이터를 보냅니다. =function(evt){ //워커로부터 데이터 함수 console.log(evt.data)를 받습니다. //워커로부터 보낸 데이터를 출력합니다.} </script> </head> <body></body>< /html>Chrome 브라우저로 test.html을 열면 콘솔에 hello world가 출력되어 프로그램이 성공적으로 실행되었음을 나타냅니다.
이 예에서 웹 작업자 사용은 주로 다음 부분으로 나누어져 있음을 알 수 있습니다.
웹 메인 스레드:
1. 작업자 = new Worker( url )를 통해 JS 파일을 로드하여 작업자를 생성하고 작업자 인스턴스를 반환합니다.
2. 작업자.postMessage(data) 메서드를 통해 작업자에게 데이터를 보냅니다.
3. 작업자가 보낸 데이터를 수신하려면 작업자.onmessage 메서드를 바인딩하세요.
4. 작업자.terminate()를 사용하여 작업자 실행을 종료할 수 있습니다.
새 작업자 스레드:
1. postMessage(data) 메소드를 통해 메인 스레드에 데이터를 보냅니다.
2. 메인 스레드에서 보낸 데이터를 수신하기 위해 onmessage 메소드를 바인딩합니다.
2: 작업자는 무엇을 할 수 있나요?이제 우리는 Web Worker를 사용하는 방법과 그 사용법, 그리고 어떤 문제를 해결하는 데 도움이 되는지 알았습니다. 피보나치 수열의 예를 살펴보겠습니다.
우리 모두 알고 있듯이, 수학에서 피보나치 수열은 재귀적으로 정의됩니다: F0=0, F1=1, Fn=F(n-1)+F(n-2) (n>=2, n∈N*), 자바스크립트의 일반적인 구현은 다음과 같습니다.
var fibonacci =function(n) { return n <2? n : 인수.callee(n -1) + 인수.callee(n -2);};//fibonacci(36)Chrome에서 39의 피보나치 수열을 계산하기 위해 이 방법을 사용하는 실행 시간은 19097밀리초이지만, 40을 계산할 때 브라우저는 스크립트가 사용 중이라는 메시지를 직접적으로 표시합니다.
JavaScript는 단일 스레드에서 실행되기 때문에 브라우저는 시퀀스를 계산하는 과정에서 다른 JavaScript 스크립트를 실행할 수 없으며 UI 렌더링 스레드도 일시 중지되어 브라우저가 좀비 상태에 들어가게 됩니다. 웹 작업자를 사용하여 시퀀스의 계산 프로세스를 새 스레드에 넣으면 이러한 상황을 피할 수 있습니다. 구체적인 예를 확인하세요:
//fibonacci.jsvar fibonacci =function(n) { return n <2? n : 인수.callee(n -1) + 인수.callee(n -2);};onmessage =function(event) { var n = parseInt (event.data, 10); postMessage(fibonacci(n));};HTML 페이지: fibonacci.html
<!DOCTYPE HTML><html><head><meta http-equiv=Content-Type content=text/html; charset=utf-8/><title>웹 작업자 fibonacci</title><script type=text/javascript > onload =function(){ var 작업자 =new Worker('fibonacci.js') 작업자.addEventListener('message', function(event) { var 타이머2 = (new Date()).valueOf(); console.log( '결과:'+event.data, '시간:'+ 타이머2, '걸린 시간:'+ ( 타이머2 - 타이머 ) }, false); ( new Date()).valueOf(); console.log('계산 시작: 40', '시간:' + 타이머 ); console.log('시퀀스를 계산할 때 타이머 함수가 실행되었습니다.', 'Time:'+ (new Date()).valueOf() },1000); 시퀀스를 계산할 때 ', 'time:'+ (new Date()).valueOf() ) } </script></head><body></body></html> 을 실행했습니다.Chrome에서 fibonacci.html을 열면 콘솔에 다음과 같은 출력이 표시됩니다.
계산 시작: 40 시간: 1316508212705
시퀀스를 계산할 때 시간을 실행했습니다: 1316508212734
시퀀스 계산 시 실행되는 타이머 함수: 1316508213735
결과: 102334155 시간: 1316508262820 경과 시간: 50115
이 예는 워커에서 수행되는 피보나치 수열의 계산이 메인 스레드의 코드 실행에 영향을 미치지 않음을 보여줍니다. 완전히 자체 독립 스레드에서 계산되며, 계산이 완료된 후에만 결과가 메인 스레드로 다시 전송됩니다. 완전한.
웹 워커를 사용하면 페이지 표시에 영향을 주지 않고 프런트 엔드에서 일부 복잡하고 대규모 작업을 수행할 수 있으며 역겨운 스크립트 사용 중 프롬프트가 팝업되지 않습니다.
다음 예에서는 웹 작업자를 사용하여 장면의 픽셀을 계산합니다. 장면이 열리면 작업자는 하나의 픽셀 값만 계산합니다.
3: 작업자의 다른 시도Worker가 URL을 수신하여 작업자를 생성한다는 것을 이미 알고 있으므로 웹 작업자를 사용하여 jsonp와 유사한 요청을 할 수 있습니까? 우리 모두 알고 있듯이 jsonp는 스크립트 태그를 삽입하여 json 데이터를 로드하고 스크립트 요소가 로드되고 실행됩니다. 프로세스가 모두 차단됩니다. 웹 작업자를 사용하여 비동기 로딩을 구현할 수 있다면 좋을 것입니다.
다음 예에서는 웹 작업자, jsonp 및 ajax의 세 가지 방법을 통해 169.42KB JSON 데이터를 로드합니다.
// /aj/webWorker/core.jsfunction $E(id) { return document.getElementById(id);}onload =function() { //웹 워커를 통해 로드 $E('workerLoad').onclick =function() { var url ='http://js.wcdn.cn/aj/mblog/face2'; var d = (new Date()).valueOf(); Worker(url); 작업자.onmessage =function(obj) { console.log('web 작업자: '+ ((new Date()).valueOf() - d)) }; E('jsonpLoad').onclick =function() { var url ='http://js.wcdn.cn/aj/mblog/face1' var d = (new Date()).valueOf(); STK.core.io.scriptLoader({ method:'post', url : url, onComplete : function() { console.log('jsonp: '+ ((new Date()) .valueOf() - d)); } }); //ajax.onclick을 통해 $E('ajaxLoad') 로드 =function() { var url ='http://js.wcdn.cn/aj/mblog/face'; var d = (new Date()).valueOf(); STK.core.io.ajax({ url : url, onComplete : function( json) { console.log('ajax: '+ ((new Date()).valueOf() - d)) };});HTML 페이지:/aj/webWorker/worker.html
<!DOCTYPE HTML><html><head><meta http-equiv=Content-Type content=text/html; charset=utf-8/><title>작업자 예: 데이터 로드</title><script src=http ://js.t.sinajs.cn/STK/js/gaea.1.14.js type=text/javascript></script><script type=text/javascript src=http://js.wcdn.cn/aj/webWorker/core.js></script></head><body> <input type=button id=workerLoad value=web 작업자 로드></input> < 입력 유형=버튼 id=jsonpLoad 값=jsonp 로드></input> <input type=버튼 id=ajaxLoad 값=ajax 로드></input></body></html>
호스트 설정
127.0.0.1 js.wcdn.cn
http://js.wcdn.cn/aj/webWorker/worker.html을 통해 페이지에 액세스한 후 세 가지 방법으로 데이터를 로드하여 콘솔 출력을 얻습니다.
웹 작업자: 174jsonp: 25ajax: 38
여러 번 시도한 결과 jsonp와 ajax를 통해 데이터를 로드하는 데 걸리는 시간 차이가 크게 다르지 않고 웹 워커의 로딩 시간이 항상 높은 수준이므로 웹 워커를 사용하여 데이터를 로드하는 것은 여전히 상대적으로 느리다는 것을 알았습니다. 데이터 양이 많은 경우 장점이 없으며 Worker가 새 스레드를 초기화하는 데 시간이 걸릴 수 있습니다. 로딩 중 논블로킹이 되는 것 외에는 장점이 없습니다.
그러면 웹 작업자가 도메인 간 js 로딩을 지원할 수 있습니까? 이번에는 http://127.0.0.1/aj/webWorker/worker.html을 통해 페이지에 액세스하면 웹 작업자 로드 버튼을 클릭하면 Chrome에 아무것도 반영되지 않습니다. 다음과 같은 오류 메시지가 나타납니다. 이를 통해 우리는 웹 작업자가 JS의 도메인 간 로딩을 지원하지 않는다는 것을 알 수 있습니다. 이는 정적 파일을 별도의 정적 서버에 배포하는 웹 사이트에 나쁜 소식입니다.
따라서 웹 작업자는 동일한 도메인에서 json 데이터를 로드하는 데만 사용할 수 있으며 ajax는 이미 이 작업을 수행할 수 있으며 더 효율적이고 다재다능합니다. 작업자가 잘하는 일을 하게 하세요.
4: 요약웹 작업자는 훌륭해 보이지만 악마적입니다.
우리가 할 수 있는 일:
1. JS를 로드하여 메인 프로세스를 중단하지 않고 수많은 복잡한 계산을 수행하고 postMessage, onmessage를 통해 통신할 수 있습니다.
2. importScripts(url)을 통해 작업자에 추가 스크립트 파일을 로드할 수 있습니다.
3. setTimeout(),clearTimeout(), setInterval(),clearInterval()을 사용할 수 있습니다.
4. XMLHttpRequest를 사용하여 요청을 보낼 수 있습니다.
5. 네비게이터의 일부 속성에 액세스할 수 있습니다.
제한 사항은 무엇입니까?
1. 도메인 간에 JS를 로드할 수 없습니다.
2. 작업자 내의 코드는 DOM에 액세스할 수 없습니다.
3. 다양한 브라우저에는 작업자 구현이 다릅니다. 예를 들어 FF에서는 작업자에서 새 작업자를 생성할 수 있지만 Chrome에서는 그렇지 않습니다.
4. 모든 브라우저가 이 새로운 기능을 지원하는 것은 아닙니다.
위의 내용은 이 기사의 전체 내용입니다. 모든 분들의 학습에 도움이 되기를 바랍니다. 또한 모든 분들이 VeVb Wulin Network를 지지해 주시길 바랍니다.