수색…


통사론

  • 새 작업자 (파일)
  • postMessage (데이터, 전송)
  • onmessage = function (message) {/ * ... * /}
  • onerror = function (message) {/ * ... * /}
  • 끝내다()

비고

  • 서비스 작업자는 HTTPS를 통해 제공되는 웹 사이트에서만 사용할 수 있습니다.

서비스 노동자 등록

// Check if service worker is available. 
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js').then(function(registration) {
    console.log('SW registration succeeded with scope:', registration.scope);
  }).catch(function(e) {
    console.log('SW registration failed with error:', e);
  });
}
  • 모든 페이지가로드 될 때마다 register() 를 호출 할 수 있습니다. SW가 이미 등록 된 경우 브라우저는 이미 실행중인 인스턴스를 제공합니다.
  • SW 파일은 모든 이름이 될 수 있습니다. sw.js 는 일반적입니다.
  • SW 파일의 위치는 SW의 범위를 정의하기 때문에 중요합니다. 예를 들어 /js/sw.js 있는 SW 파일은 /js/ 시작하는 파일의 fetch 요청을 인터셉트 할 수만 있습니다. 이러한 이유로 보통 프로젝트의 최상위 디렉토리에서 SW 파일을 보게됩니다.

웹 작업자

작업자 스레드가 사용자 인터페이스를 방해하지 않고 작업 (xmlHttpRequest를 사용하는 I / O 작업 포함)을 수행 할 수 있으므로 웹 작업자는 백그라운드 스레드에서 스크립트를 실행할 수있는 간단한 방법입니다. 일단 작성된 작업자는 다른 데이터 유형 (함수 제외)이 될 수있는 메시지를 해당 코드로 지정된 이벤트 핸들러에 메시지를 게시하여 생성 한 JavaScript 코드에 보낼 수 있습니다.

근로자는 몇 가지 방법으로 창출 될 수 있습니다.

가장 일반적인 방법은 간단한 URL을 이용하는 것입니다.

var webworker = new Worker("./path/to/webworker.js");

URL.createObjectURL() 사용하여 문자열에서 동적으로 Worker를 만들 수도 있습니다.

var workerData = "function someFunction() {}; console.log('More code');";

var blobURL = URL.createObjectURL(new Blob(["(" + workerData + ")"], { type: "text/javascript" }));

var webworker = new Worker(blobURL);

동일한 메소드를 Function.toString() 과 결합하여 기존 함수에서 작업자를 만들 수 있습니다.

var workerFn = function() {
    console.log("I was run");
};

var blobURL = URL.createObjectURL(new Blob(["(" + workerFn.toString() + ")"], { type: "text/javascript" }));

var webworker = new Worker(blobURL);

간단한 봉사원

main.js

서비스 근로자는 출발지와 경로에 대해 등록 된 이벤트 중심 근로자입니다. 연결된 웹 페이지 / 사이트를 제어하고 탐색 및 리소스 요청을 가로 채고 수정하며 리소스를 매우 세부적으로 캐싱하여 특정 상황에서 앱의 동작 방식을 완벽하게 제어 할 수있는 JavaScript 파일 형식을 취합니다 (가장 명백한 것은 네트워크를 사용할 수없는 경우입니다.)

출처 : MDN

몇 가지 사항 :

  1. 자바 스크립트 워커이므로 DOM에 직접 액세스 할 수 없습니다.
  2. 프로그래밍 가능한 네트워크 프록시
  3. 사용하지 않을 때 종료되고 다음에 필요할 때 다시 시작됩니다.
  4. 서비스 작업자는 웹 페이지와 완전히 별개의 라이프 사이클을 가지고 있습니다.
  5. HTTPS가 필요합니다.

Document 컨텍스트에서 실행될이 코드는 (또는)이 JavaScript가 <script> 태그를 통해 페이지에 포함됩니다.

// we check if the browser supports ServiceWorkers
if ('serviceWorker' in navigator) {
  navigator
    .serviceWorker
    .register(
      // path to the service worker file
      'sw.js'
    )
    // the registration is async and it returns a promise
    .then(function (reg) {
      console.log('Registration Successful');
    });
}

sw.js

이것은 서비스 작업자 코드이며 ServiceWorker 전역 범위 에서 실행됩니다.

self.addEventListener('fetch', function (event) {
  // do nothing here, just log all the network requests
  console.log(event.request.url);
});

헌신적 인 노동자와 공유 된 노동자

헌신적 인 노동자

전용 웹 작업자는 스크립트를 호출 한 스크립트에서만 액세스 할 수 있습니다.

주요 용도 :

var worker = new Worker('worker.js');
worker.addEventListener('message', function(msg) {
    console.log('Result from the worker:', msg.data);
});
worker.postMessage([2,3]);

worker.js :

self.addEventListener('message', function(msg) {
    console.log('Worker received arguments:', msg.data);
    self.postMessage(msg.data[0] + msg.data[1]);
});

공유 된 근로자

공유 작업자는 여러 창, iframe 또는 심지어 근로자가 액세스하는 경우에도 여러 스크립트로 액세스 할 수 있습니다.

공유 작업자를 만드는 것은 전용 태스크를 만드는 방법과 매우 유사하지만 주 스레드와 작업자 스레드 간의 직접적인 통신 대신 포트 객체를 통해 통신해야합니다. 즉, 명시 적 포트가 있어야합니다. 여러 스크립트가 공유 작업자와 통신하는 데 사용할 수 있도록 열 수 있습니다. (헌신적 인 노동자는 이것을 암묵적으로 행한다는 점에 유의하십시오)

주요 용도

var myWorker = new SharedWorker('worker.js');
myWorker.port.start();  // open the port connection

myWorker.port.postMessage([2,3]);

worker.js

self.port.start(); open the port connection to enable two-way communication

self.onconnect = function(e) {
    var port = e.ports[0];  // get the port

    port.onmessage = function(e) {
        console.log('Worker revceived arguemnts:', e.data);
        port.postMessage(e.data[0] + e.data[1]);
    }
}

작업자 스레드에서이 메시지 처리기를 설정하면 암시 적으로 포트 연결이 상위 스레드로 다시 열리므로 port.start() 대한 호출이 위에 언급 된 것처럼 실제로 필요하지 않습니다.

근로자 해지

일단 일을 끝내면 일을 끝내야합니다. 이렇게하면 사용자 컴퓨터의 다른 응용 프로그램에 대한 리소스를 확보 할 수 있습니다.

메인 주제 :

// Terminate a worker from your application.
worker.terminate();

참고 : 서비스 근로자는 terminate 방법을 사용할 수 없습니다. 사용하지 않을 때 종료되고 다음에 필요할 때 다시 시작됩니다.

작업자 스레드 :

// Have a worker terminate itself.
self.close();

캐시 채우기

서비스 직원이 등록 된 후 브라우저는 서비스 사원을 설치하고 나중에 활성화하려고 시도합니다.

이벤트 리스너 설치

this.addEventListener('install', function(event) {
    console.log('installed');
});

캐싱

이 설치 이벤트를 사용하여 오프라인에서 앱을 실행하는 데 필요한 애셋을 캐싱 할 수 있습니다. 아래 예제에서는 캐시 API를 사용하여 동일한 작업을 수행합니다.

this.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open('v1').then(function(cache) {
      return cache.addAll([
        /* Array of all the assets that needs to be cached */
        '/css/style.css',
        '/js/app.js',
        '/images/snowTroopers.jpg'
      ]);
    })
  );
});

웹 작업자와 의사 소통하기

작업자는 작업자와 별도의 스레드에서 실행되므로 postMessage 를 통해 통신해야합니다.

참고 : 내보내기 접두사가 다르기 때문에 일부 브라우저에는 postMessage 대신 webkitPostMessage 가 있습니다. postMessage 를 오버라이드하여 가능한 한 많은 장소에서 근로자가 "일하도록"(말장난 없음) 확인해야합니다.

worker.postMessage = (worker.webkitPostMessage || worker.postMessage);

주 스레드 (상위 창)에서 :

// Create a worker
var webworker = new Worker("./path/to/webworker.js");

// Send information to worker
webworker.postMessage("Sample message");

// Listen for messages from the worker
webworker.addEventListener("message", function(event) {
    // `event.data` contains the value or object sent from the worker
    console.log("Message from worker:", event.data); // ["foo", "bar", "baz"]
});

웹 근로자의 webworker.js 에서

// Send information to the main thread (parent window)
self.postMessage(["foo", "bar", "baz"]);

// Listen for messages from the main thread
self.addEventListener("message", function(event) {
    // `event.data` contains the value or object sent from main
    console.log("Message from parent:", event.data); // "Sample message"
});

또는 onmessage 사용하여 이벤트 리스너를 추가 할 수도 있습니다.

주 스레드 (상위 창)에서 :

webworker.onmessage = function(event) {
    console.log("Message from worker:", event.data); // ["foo", "bar", "baz"]
}

웹 근로자의 webworker.js 에서

self.onmessage = function(event) {
    console.log("Message from parent:", event.data); // "Sample message"
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow