어떻게 Angular의 다른 라인에서 웹 워커와 함수를 실행합니까
23440 단어 angulartutorialjavascript
web workers가 있으면 우리는 백엔드 라인에서 스크립트를 실행하고 메인 라인을 사용자 인터페이스에 남겨 둘 수 있다.기본적으로 웹 작업자는 파일 URL을 매개 변수로 받아들이지만, 우리의 경우 이것은 받아들일 수 없습니다. 왜냐하면 우리는 TypeScript를 주 언어로 사용하고 자바스크립트와 혼합하여 사용하고 싶지 않기 때문입니다.두 번째 문제는 스크립트에 고정된 URL이 있어야 한다는 것이다. 우리는 웹 팩을 사용하여 파일을 연결하기 때문에 연결되지 않은 파일을 가지고 있는 것이 가장 좋은 패턴이 아니다.
Worker류는 ServiceWorker과SharedWorker의 기이다.SharedWorker는 Worker와 유사하지만, 팝업 창, iFrame 등 여러 가지 상하문에서 접근할 수 있습니다. ServiceWorker는 본 쇼케이스의 주제가 아니라 다른 beast입니다.
작업 스레드가 실행되는 코드는 주 스레드에서 실행되는 코드와 다른 상하문에서 실행됩니다.Worker에서 코드를 실행할 때, DOM 요소를 조작할 수 없고, 창 대상을 사용할 수 없습니다. Worker가 실행하는 상하문은 DedicatedWorkerGlobalScope 이며, 사용자가 접근할 수 있고 통상적으로 실행할 수 있는 작업에 한계가 있습니다.
Worker의 일반적인 예는 복잡한 처리를 수행하는 순수한 함수를 사용하는 것입니다.웹 응용 프로그램의 성능을 파괴하는 것을 원하지 않기 때문에, 작업 라인으로 옮겨야 합니다.
작업 스레드는
postMessage 방법의 메시지를 통해 주 스레드와 통신할 수 있다.통신이 양방향일 수 있다는 것은 작업 라인과 주 라인이 서로 메시지를 보낼 수 있다는 것을 의미한다.
주 라인과 작업 라인은 서로 정탐하고 메시지를 보낼 수 있다.
인라인워커 클래스를 만듭니다. 이 클래스는 하나의 함수를 매개 변수로 받아들이고 다음 그림과 같이 다른 라인에서 이 함수를 실행합니다.
import { Observable, Subject } from 'rxjs';
export class InlineWorker {
private readonly worker: Worker;
private onMessage = new Subject<MessageEvent>();
private onError = new Subject<ErrorEvent>();
constructor(func) {
const WORKER_ENABLED = !!(Worker);
if (WORKER_ENABLED) {
const functionBody = func.toString().replace(/^[^{]*{\s*/, '').replace(/\s*}[^}]*$/, '');
this.worker = new Worker(URL.createObjectURL(
new Blob([ functionBody ], { type: 'text/javascript' })
));
this.worker.onmessage = (data) => {
this.onMessage.next(data);
};
this.worker.onerror = (data) => {
this.onError.next(data);
};
} else {
throw new Error('WebWorker is not enabled');
}
}
postMessage(data) {
this.worker.postMessage(data);
}
onmessage(): Observable<MessageEvent> {
return this.onMessage.asObservable();
}
onerror(): Observable<ErrorEvent> {
return this.onError.asObservable();
}
terminate() {
if (this.worker) {
this.worker.terminate();
}
}
}
위에 표시된 코드에서 가장 중요한 부분은 클래스입니다. 이 클래스는 함수를 문자열로 변환하여 생성합니다ObjectURL. 이 클래스는 구조 함수를 통해 작업 클래스에 전달됩니다.const functionBody = func.toString().replace(/^[^{]*{\s*/, '').replace(/\s*}[^}]*$/, '');
this.worker = new Worker(URL.createObjectURL(
new Blob([ functionBody ], { type: 'text/javascript' })
));
InlineWorker 클래스 사용 방법
만약 우리가 Angular 함수 (위 코드 블록에서 보듯이 클래스) 를 가지고 있다면, 우리는 백그라운드에서 그것을 처리하기를 희망한다.
우리는 우리가 범위 내에 얼마나 많은 소수를 가지고 있는지 계산하기 위해 응용 프로그램을 구축할 것이다.
주 루틴은 작업 루틴에 제한 파라미터를 보냅니다. 루틴이 작업을 완성하면 주 루틴에 결과를 생성하고 작업 루틴을 종료합니다.
주의해야 할 것은 인라인워커에 전달된 리셋 함수 외에 정의된 방법, 변수, 함수를 사용할 수 없다는 것이다.
만약 우리가 매개 변수 (postMessage functions accept anything as parameters 를 전달해야 한다면, 우리는
postMessage 방법을 사용해야 한다.import { Component, OnInit } from '@angular/core';
import { InlineWorker } from './inlineworker.class';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
result = 0;
ngOnInit() {
const worker = new InlineWorker(() => {
// START OF WORKER THREAD CODE
console.log('Start worker thread, wait for postMessage: ');
const calculateCountOfPrimeNumbers = (limit) => {
const isPrime = num => {
for (let i = 2; i < num; i++) {
if (num % i === 0) { return false; }
}
return num > 1;
};
let countPrimeNumbers = 0;
while (limit >= 0) {
if (isPrime(limit)) { countPrimeNumbers += 1; }
limit--;
}
// this is from DedicatedWorkerGlobalScope ( because of that we have postMessage and onmessage methods )
// and it can't see methods of this class
// @ts-ignore
this.postMessage({
primeNumbers: countPrimeNumbers
});
};
// @ts-ignore
this.onmessage = (evt) => {
console.log('Calculation started: ' + new Date());
calculateCountOfPrimeNumbers(evt.data.limit);
};
// END OF WORKER THREAD CODE
});
worker.postMessage({ limit: 300000 });
worker.onmessage().subscribe((data) => {
console.log('Calculation done: ', new Date() + ' ' + data.data);
this.result = data.data.primeNumbers;
worker.terminate();
});
worker.onerror().subscribe((data) => {
console.log(data);
});
}
}
보시다시피 익명 함수는 인라인워커에 매개 변수로 전달됩니다.전달된 함수의 상하문은 격리되어 있으며, 이것은 우리가 그 이외의 어떤 내용도 방문할 수 없다는 것을 의미한다.만약 우리가 이렇게 하려고 시도한다면, 그것은 정의되지 않을 것이다.우리의 응용 프로그램 절차는 다음과 같다.
현재 컨텍스트에서 정의를 읽을 수 없기 때문에 @ts ignore comment를 postMessage 및
onmessage 방법 앞에 두어야 합니다.이 경우 TypeScript는 큰 도움이 되지 않습니다.리셋 함수 중의 탐지기
onmessage는 탐지기를 이 작업자에게 전달하는 모든 정보를 우리의 예시에서 호출calculateCountOfPrimeNumbers하고 매개 변수를 전달합니다.함수는 계산을 하고
postMessage 방법으로 주 라인에서 탐지기에 결과를 생성합니다.사용:
worker.postMessage({ limit: 10000 });
우리는 작업 라인의 집행을 촉발할 것이다.Angular에서 이 예시를 작성할 때 RXJS 관찰 값을 사용하여 데이터 변경 사항을 전달하고 수신합니다.다음 줄에서 우리는 일꾼으로부터 온 소식을 구독하고 있다.
worker.onmessage().subscribe((data) => {
console.log(data.data);
worker.terminate();
});
간단하게 말하자면, 우리는 결과를 컨트롤러에 출력한 다음에worker를 종료합니다. 그러면 더 이상 그것을 사용할 수 없습니다.우리는 위의 예시처럼 하나의 실행을 잠그지 않고 하나의 작업 라인에 여러 개의 메시지를 보내고 여러 개의 결과를 받을 수 있다.Google 구독
onerrorobservable는 매우 중요합니다. 이것은 작업 라인에서 발생하는 오류를 보는 유일한 방법이기 때문입니다.프레젠테이션 시간
다음은 Worker의 프레젠테이션입니다. https://angular-with-worker-logrocket.surge.sh/(UI를 막지 않음)
이것은 Worker가 없는 데모입니다. https://angular-without-worker-logrocket.surge.sh/(계산이 실행될 때 UI가 막힙니다)
결론
본고에서 우리는 번거로운 처리를 메인 라인에서 백엔드 라인으로 옮겨 메인 라인을 막지 않고 응용 프로그램에서 좋은 사용자 체험을 제공하는 방법을 배웠다.
인터넷 종사자part of the Web APIs는 브라우저에서만 사용할 수 있다는 것을 의미하며, 주의해야 할 것은 그들well supported in all major browsers이다.
편집자: 이 문장에 무슨 문제가 있습니까?정확한 버전here을 찾을 수 있습니다.
플러그인: 네트워크 어플리케이션용 DVR용 LogRocket
LogRocket는 프런트엔드 로그 기록 도구로 자신의 브라우저에서처럼 문제를 재생할 수 있다.LogRocket은 오류가 발생한 원인을 추측하거나 화면 캡처와 로그 저장을 물어보지 않고 세션을 다시 재생할 수 있도록 합니다.프레임워크가 어떻든지 간에 모든 응용 프로그램과 완벽하게 어울릴 수 있으며, 플러그인은 Redux, Vuex, @ngrx/store의 추가 상하문을 기록합니다.
LogRocket은 Redux 작업과 상태를 기록하는 것 외에도 콘솔 로그, JavaScript 오류, 스택 추적, 헤더+본문이 있는 네트워크 요청/응답, 브라우저 메타데이터와 사용자 정의 로그를 기록합니다.또한 DOM은 페이지의 HTML과 CSS를 기록하여 가장 복잡한 단일 페이지 응용 프로그램이라도 픽셀 수준의 비디오를 재구성합니다.
Try it for free .
게시물How to execute a function with a web worker on a different thread in Angular이 먼저 LogRocket Blog에 올라왔다.
Reference
이 문제에 관하여(어떻게 Angular의 다른 라인에서 웹 워커와 함수를 실행합니까), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/bnevilleoneill/how-to-execute-a-function-with-a-web-worker-on-a-different-thread-in-angular-akh텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)