WASM 및 웹 작업자를 사용하여 브라우저에서 Go 실행
12978 단어 languagesgowebassemblyjavascript

게시물Running Go in the Browser with WASM and Web Workers은 Qvault에 처음 등장했습니다.
최근 Qvault의 브라우저에서 Go를 실행하는 방법을 크게 변경했으며 향상된 기능에 대해 설명하고자 합니다. 웹 작업자는 우리를 방해했던 심각한 브라우저 관련 코딩 문제를 해결할 수 있었던 이유입니다. 이 기사는 Running Go in the Browser with Web Assembly의 속편이라고 생각하십시오.
최신 과정Big-O Algorithms을 게시하는 동안 코드가 계속 실행되는 동안 콘솔 출력을 인쇄하는 방법이 필요했습니다. 브라우저에서 계산 비용이 많이 드는 알고리즘을 실행할 때 문제가 발생했습니다. 브라우저가 너무 느려서 새로운 출력 라인을 렌더링할 수 없습니다. 우리는 웹 작업자를 구현하기로 결정했고 그들은 문제를 쉽게 해결했습니다.
문제
이전 Qvault에서는 콘솔 출력이 모두 한 번에 인쇄되었습니다. 프로그램이 실행된 다음 출력이 표시되었습니다. 특히 속도를 위해 알고리즘을 최적화하려고 할 때 무언가가 인쇄될 때 확인하는 것이 종종 유용하기 때문에 이것이 이상적이지 않다는 것을 알았습니다.
예를 들어 다음 코드는 모든 출력을 한 번에 인쇄하는 데 사용됩니다.
package main
import (
"fmt"
)
func main(){
const max = 100000000
for i := 0; i < max; i++{
if i % (max/10) == 0{
fmt.Println(i)
}
}
}
웹 작업자를 추가한 이후로 이제 실행 시 각 숫자를 적절하게 인쇄합니다. playground here에서 직접 확인할 수 있습니다.
웹 작업자란 무엇입니까?
Web Workers are a simple means for web content to run scripts in background threads.
즉, JavaScript의 단일 스레드 클러치에서 마침내 자유로울 수 있는 방법입니다! 비용이 많이 드는 작업을 다른 실행 스레드로 오프로드할 수 있습니다. 이렇게 하면 브라우저가 자유롭게 화면에 업데이트를 렌더링할 수 있습니다.
작동 방식 – 작업자
아시다시피 저희는 편집기의 코드를 저희 서버의 WASM으로 컴파일합니다. 그 부분이 궁금하시다면 저희previous post.에서 읽어보실 수 있습니다. 코드가 웹 어셈블리로 컴파일되면 실행을 위해 프런트 엔드로 다시 배송됩니다.
Web Worker를 실행하려면 작업자를 정의하는 스크립트가 필요합니다. 자바스크립트 파일일 뿐입니다.
addEventListener('message', async (e) => {
// initialize the Go WASM glue
const go = new self.Go();
// e.data contains the code from the main thread
const result = await WebAssembly.instantiate(e.data, go.importObject);
// hijack the console.log function to capture stdout
let oldLog = console.log;
// send each line of output to the main thread
console.log = (line) => { postMessage({
message: line
}); };
// run the code
await go.run(result.instance);
console.log = oldLog;
// tell the main thread we are done
postMessage({
done: true
});
}, false);
작업자는
message
이벤트를 수신하고 postMessage
함수를 통해 데이터를 다시 전송하여 기본 스레드와 통신합니다.참고: 작업자가 Go 코드를 실행하는 데 필요한 wasm_exec.js 파일을 생략했지만 Go가 설치되어 있으면 컴퓨터에서 찾을 수 있습니다.
cat $(go env GOROOT)/misc/wasm/wasm_exec.js
작동 방식 – 메인 스레드
이제 컴파일된 웹 어셈블리를 실행할 수 있는 작업자 파일이 있으므로 메인 스레드가 작업자와 통신하는 방법을 살펴보겠습니다. 일부 도우미 기능을 내보내는 ES6 모듈을 만들었습니다.
export function getWorker(lang) {
return {
webWorker: new window.Worker(`/${lang}_worker.js`),
lang
};
}
export function useWorker(worker, params, callback) {
const promise = new Promise((resolve, reject) => {
worker.webWorker.onmessage = (event) => {
if (event.data.done) {
resolve();
return;
}
if (event.data.error) {
reject(event.data.error);
return;
}
callback(event.data.message);
};
});
worker.webWorker.postMessage(params);
return promise;
}
export function terminateWorker(worker) {
worker.webWorker.terminate();
}
페이지가 로드되면
getWorker
를 사용하여 새 웹 작업자를 만듭니다. 사용자가 일부 코드를 실행하면 useWorker
를 사용하여 작업자에게 코드를 보냅니다. 코드 편집기에서 벗어날 때 terminateWorker
를 사용하여 작업자를 정리할 수 있습니다.useWorker
함수는 게시물에서 흥미로운 부분입니다. getWorker
로 생성된 작업자, 작업자에게 전달될 params
라는 객체(컴파일된 WASM 포함) 및 작업자가 작업을 완료할 때 실행할 콜백 함수를 사용합니다.예를 들어 Vue 앱에서는 다음과 같이 이러한 기능을 사용합니다.
this.output = [];
this.isLoading = true;
const wasm = await compileGo(this.code);
await useWorker(this.worker, wasm, (data) => {
this.output.push(data);
});
this.isLoading = false;
그리고
this.output
는 Vue 인스턴스의 반응형 속성이므로 Web Worker에서 데이터를 받을 때마다 새 출력이 콘솔에 출력됩니다.읽어 주셔서 감사합니다!
질문이나 의견이 있으면 Twitter에서 팔로우하세요.
좀 가져가 coding courses on our new platform
Subscribe 더 많은 프로그래밍 기사를 보려면 뉴스레터로
Reference
이 문제에 관하여(WASM 및 웹 작업자를 사용하여 브라우저에서 Go 실행), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/wagslane/running-go-in-the-browser-with-wasm-and-web-workers-4ac8텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)