ã¦ã§ãã¯ã¼ã«ã¼ã¯ãã¦ã§ãã³ã³ãã³ããã¹ã¯ãªãããããã¯ã°ã©ã¦ã³ãã®ã¹ã¬ããã§å®è¡ããããã®ã·ã³ãã«ãªææ®µã§ããã¯ã¼ã«ã¼ã¹ã¬ããã¯ãã¦ã¼ã¶ã¼ã¤ã³ã¿ã¼ãã§ã¤ã¹ã妨ãããã¨ãªãã¿ã¹ã¯ãå®è¡ã§ãã¾ããããã«ã fetch()
ã XMLHttpRequest
ãªã© API ãç¨ãã¦ããããã¯ã¼ã¯ãªã¯ã¨ã¹ããè¡ããã¨ãã§ãã¾ããã¯ã¼ã«ã¼ãçæãããã¨ãããã使ãã JavaScript ã³ã¼ããæå®ããã¤ãã³ããã³ãã©ã¼ã«ã¡ãã»ã¼ã¸ãæç¨¿ãããã¨ã§ããã®ã³ã¼ãã«ã¡ãã»ã¼ã¸ãéããã¨ãã§ãã¾ãï¼éãåæ§ï¼ã
ãã®è¨äºã§ã¯ãã¦ã§ãã¯ã¼ã«ã¼ã使ç¨ããããã®è©³ããç´¹ä»ããã¦ãã¾ãã
ã¦ã§ãã¯ã¼ã«ã¼ APIã¯ã¼ã«ã¼ã¯ã³ã³ã¹ãã©ã¯ã¿ã¼ï¼Worker()
ãªã©ï¼ã使ç¨ãã¦çæããããªãã¸ã§ã¯ãã§ãããååä»ãã® JavaScript ãã¡ã¤ã«ï¼ãã®ãã¡ã¤ã«ã¯ã¯ã¼ã«ã¼ã¹ã¬ããã§å®è¡ããã³ã¼ããæã¡ã¾ãï¼ãå®è¡ãã¾ããã¾ãã¯ã¼ã«ã¼ã¯ãç¾å¨ã® window
ã¨ã¯ç°ãªãã°ãã¼ãã«ã³ã³ããã¹ãã§å®è¡ããã¾ããå¾ã£ã¦ã window
ãï¼self
ã®ä»£ããã«ï¼ä½¿ç¨ãã¦ç¾å¨ã®ã°ãã¼ãã«ã¹ã³ã¼ããåå¾ãããã¨ããã¨ã Worker
ã®ä¸ã§ã¯ã¨ã©ã¼ãè¿ããã¾ãã
ã¯ã¼ã«ã¼ã®ã³ã³ããã¹ãã¯ãå°ç¨ã¯ã¼ã«ã¼ï¼åä¸ã®ã¹ã¯ãªããã§å©ç¨ãããæ¨æºçãªã¯ã¼ã«ã¼ï¼ã®å ´å㯠DedicatedWorkerGlobalScope
ãªãã¸ã§ã¯ãã§è¡¨ããã¾ãï¼å
±æã¯ã¼ã«ã¼ã®å ´å㯠SharedWorkerGlobalScope
ã§ãï¼ãå°ç¨ã¯ã¼ã«ã¼ã¯ãæåã«ã¯ã¼ã«ã¼ãèµ·åããã¹ã¯ãªããã ããã¢ã¯ã»ã¹ã§ãã¾ãã䏿¹ãå
±æã¯ã¼ã«ã¼ã¯è¤æ°ã®ã¹ã¯ãªããããã¢ã¯ã»ã¹ã§ãã¾ãã
ã¡ã¢: ã¯ã¼ã«ã¼ã®ãªãã¡ã¬ã³ã¹ããã¥ã¡ã³ãã追å ã®ã¬ã¤ãã«ã¤ãã¦ã¯ãã¦ã§ãã¯ã¼ã«ã¼ API ã®ããããã¼ã¸ãã覧ãã ããã
ã¯ã¼ã«ã¼ã¹ã¬ããã§ã¯ãã©ã®ãããªã³ã¼ãã§ãå®è¡ã§ãã¾ãããããã¤ãã®å¶éãããã¾ããä¾ãã°ãã¯ã¼ã«ã¼å
ããç´æ¥ DOM ãæä½ãããã¨ã¯ã§ãã¾ãããã¾ã window
ãªãã¸ã§ã¯ãã®æ¢å®ã®ã¡ã½ãããããããã£ã§ã使ç¨ã§ããªããã®ãããã¾ããããã§ããwindow
é
ä¸ã«ãã夿°ã®é
ç®ããã¨ãã° WebSocket ãã IndexedDB ã®ãããªãã¼ã¿ã¹ãã¬ã¼ã¸æ©æ§ãªã©ã使ç¨ã§ãã¾ãã詳ããã¯ã¯ã¼ã«ã¼ã§ä½¿ç¨ã§ãã颿°ãã¯ã©ã¹ãã覧ãã ããã
ã¯ã¼ã«ã¼ã¨ã¡ã¤ã³ã¹ã¬ããã®éã§ãã¼ã¿ãããåãããã«ã¯ãã¡ãã»ã¼ã¸ã®ä»çµã¿ã使ç¨ããã¾ããã©ã¡ãã postMessage()
ã¡ã½ããã使ç¨ãã¦ã¡ãã»ã¼ã¸ãéä¿¡ããonmessage
ã¤ãã³ããã³ãã©ã¼ã«ãã£ã¦ã¡ãã»ã¼ã¸ã«å¿çãã¾ãï¼ã¡ãã»ã¼ã¸ã¯ message
ã¤ãã³ãã® data 屿§ã«åãããã¾ãï¼ããã¼ã¿ã¯å
±æããããè¤è£½ããã¾ãã
ã¯ã¼ã«ã¼ã¯ã親ãã¼ã¸ã¨åããªãªã¸ã³å ã§ãã¹ãã£ã³ã°ããã¦ããéããæ°ããã¯ã¼ã«ã¼ãçã¿åºããã¨ãã§ãã¾ãã
ã¾ããã¯ã¼ã«ã¼ã¯ fetch()
ã XMLHttpRequest
ãªã©ã® API ãç¨ãã¦ããããã¯ã¼ã¯ãªã¯ã¨ã¹ããè¡ããã¨ãã§ãã¾ãï¼ãã ããXMLHttpRequest
ã® responseXML
屿§ã¯å¸¸ã« null
ã«ãªããã¨ã«æ³¨æãã¦ãã ããï¼ã
åè¿°ã®ã¨ãããå°ç¨ã¯ã¼ã«ã¼ (dedicated worker) ã«ã¯å¼ã³åºãå ã®ã¹ã¯ãªããã ããã¢ã¯ã»ã¹ã§ãã¾ãããã®ç¯ã§ã¯åºæ¬çãªå°ç¨ã¯ã¼ã«ã¼ã®ãµã³ãã«ã«ãã JavaScript ãè¦ã¦ããã¾ãï¼å°ç¨ã¯ã¼ã«ã¼ãå®è¡ããï¼ãããã¯ã 2 ã¤ã®æ°åãå ¥åãã¦æãåããããã¨ãã§ãããã®ã§ããæ°åã¯å°ç¨ã®ã¯ã¼ã«ã¼ã«éããã¦æãåãããããã®çµæããã¼ã¸ã«æ»ããã¦è¡¨ç¤ºããã¾ãã
ããã¯ãã¾ãé¢ç½ã¿ã®ãªããµã³ãã«ã§ãããåºæ¬çãªã¯ã¼ã«ã¼ã®æ¦å¿µãç´¹ä»ããéã¯ã·ã³ãã«ã«ä¿ã¨ãã¨èãã¦ãã¾ããããé«åº¦ãªè©³ç´°æ å ±ã¯ããã®è¨äºã®å¾åã§æ±ãã¾ãã
ã¯ã¼ã«ã¼ã®æ©è½æ¤åºã¨ã©ã¼å¶å¾¡ã¨å¾æ¹äºææ§ãåä¸ããããããã¯ã¼ã«ã¼ã«ã¢ã¯ã»ã¹ããã³ã¼ãã¯ä»¥ä¸ã®ã³ã¼ãã®ä¸ã«å ¥ããã¨ããã§ããã (main.js)ã
if (window.Worker) {
// â¦
}
å°ç¨ã¯ã¼ã«ã¼ã®èµ·å
æ°ããã¯ã¼ã«ã¼ã¯ç°¡åã«çæã§ãã¾ããå¿
è¦ãªãã¨ã¯ãã¯ã¼ã«ã¼ã¹ã¬ããã§å®è¡ããã¹ã¯ãªããã® URI ãæå®ãã Worker()
ã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã³åºããã¨ã ãã§ã (main.js)ã
const myWorker = new Worker("worker.js");
ã¡ã¢: webpackãViteãParcel ãªã©ã®ãã³ãã©ã¼ã§ã¯ã import.meta.url
ã«å¯¾ãã¦ç¸å¯¾çã«è§£æ±ºããã URL ã Worker()
ã³ã³ã¹ãã©ã¯ã¿ã¼ã«æ¸¡ããã¨ãæ¨å¥¨ãã¦ãã¾ããä¾ãã°ã次ã®ããã«ãã¾ãã
const myWorker = new Worker(new URL("worker.js", import.meta.url));
ãããããã¨ã§ããã¹ã¯ç¾å¨ã® HTML ãã¼ã¸ã§ã¯ãªãç¾å¨ã®ã¹ã¯ãªãããåºæºã¨ããããããã³ãã©ã¼ã¯ãåå夿´ãªã©ã®æé©åãå®å
¨ã«è¡ããã¨ãã§ãã¾ãï¼ããããªãã¨ãworker.js
ã® URL ããã³ãã©ã¼ã管çãã¦ããªããã¡ã¤ã«ãæãå¯è½æ§ãããããã³ãã©ã¼ã¯ä»®å®ãç«ã¦ããã¨ãã§ããªããªãããã§ãï¼ã
ã¯ã¼ã«ã¼ã®ãã¸ãã¯ã¯ãpostMessage()
ã¡ã½ãã㨠onmessage
ã¤ãã³ããã³ãã©ã¼ã«ãã£ã¦å®ç¾ãã¾ããã¯ã¼ã«ã¼ã«ã¡ãã»ã¼ã¸ãéãããã¨ãã¯ã以ä¸ã®ããã«ãã¦ã¡ãã»ã¼ã¸ãéä¿¡ãã¾ã (main.js)ã
[first, second].forEach((input) => {
input.onchange = () => {
myWorker.postMessage([first.value, second.value]);
console.log("ã¡ãã»ã¼ã¸ãã¯ã¼ã«ã¼ã«æ¸¡ããã¾ãã");
};
});
2 ã¤ã® <input>
è¦ç´ ãããããããã夿° first
㨠second
ã§è¡¨ããã¦ãã¾ããã©ã¡ããã®å¤ãå¤åããã¨ã myWorker.postMessage([first.value,second.value])
ã使ç¨ãã¦ãåæ¹ã®å¤ãé
åã¨ãã¦ã¯ã¼ã«ã¼ã«éä¿¡ãã¾ããã¡ãã»ã¼ã¸ã§ã¯ãããããã©ã®ãããªãã®ã§ãéä¿¡ã§ãã¾ãã
ã¯ã¼ã«ã¼å ã§ã¯ã以ä¸ã®ããã«ã¤ãã³ããã³ãã©ã¼ã®ãããã¯ã«ã³ã¼ããè¨è¿°ããã¨ãã¡ãã»ã¼ã¸ãåãåã£ãã¨ãã«å¿çã§ãã¾ã (worker.js)ã
onmessage = (e) => {
console.log("Message received from main script");
const workerResult = `Result: ${e.data[0] * e.data[1]}`;
console.log("Posting message back to main script");
postMessage(workerResult);
};
onmessage
ãã³ãã©ã¼ã«ãããã¡ãã»ã¼ã¸ãåãåã£ãã¨ãã«ãªãããã®ã³ã¼ããå®è¡ã§ãã¾ããã¡ãã»ã¼ã¸èªä½ã¯ãmessage
ã¤ãã³ãã® data
屿§ã§æã«å
¥ãã¾ããããã§ã¯ 2 ã¤ã®æ°å¤ã§ä¹ç®ãè¡ã£ãå¾ãåã³ postMessage()
ã使ç¨ãã¦è¨ç®çµæãã¡ã¤ã³ã¹ã¬ããã«è¿ãã¦ãã¾ãã
ã¡ã¤ã³ã¹ã¬ããã«æ»ãã¨ãåã³ onmessage
ã使ç¨ãã¦ãã¯ã¼ã«ã¼ããè¿ãããã¡ãã»ã¼ã¸ã«å¿çãã¾ãã
myWorker.onmessage = (e) => {
result.textContent = e.data;
console.log("ã¡ãã»ã¼ã¸ãã¯ã¼ã«ã¼ããåä¿¡ãã¾ãã");
};
ããã§ã¯ã¡ãã»ã¼ã¸ã¤ãã³ããããã¼ã¿ãåãåºãã¦ãçµæã®æ®µè½ã® textContent
ã¸æ ¼ç´ãã¦ãã¾ããããã§ãã¦ã¼ã¶ã¼ã¯è¨ç®çµæãè¦ããã¨ãã§ãã¾ãã
ã¡ã¢: ã¡ã¤ã³ã®ã¹ã¯ãªããã¹ã¬ããã§ onmessage
ããã³ postMessage()
ã使ç¨ããã¨ã㯠Worker
ãªãã¸ã§ã¯ãã«ã¶ãä¸ããªããã°ãªãã¾ããããã¯ã¼ã«ã¼å
ã§ã¯ãã®ããã«ããå¿
è¦ã¯ããã¾ãããããã¯ãã¯ã¼ã«ã¼å
ã§ã¯ããèªèº«ãå®è³ªçãªã°ãã¼ãã«ã¹ã³ã¼ãã«ãªãããã§ãã
ã¡ã¢: ã¡ãã»ã¼ã¸ãã¡ã¤ã³ã¹ã¬ããã¨ã¯ã¼ã«ã¼ã®éã§ããã¨ãããã¨ããå ±æãããã®ã§ã¯ãªããè¤è£½ã¾ãã¯ãç§»è²ãï¼ç§»åï¼ããã¾ãã詳ãã解説ã¯ãã¯ã¼ã«ã¼ã¨ã®ãã¼ã¿è»¢éã®è©³ç´°ãã覧ãã ããã
ã¯ã¼ã«ã¼ã®çµäºã¡ã¤ã³ã¹ã¬ããããå®è¡ãã¦ããã¯ã¼ã«ã¼ãç´ã¡ã«çµäºãããå¿
è¦ãããå ´åã¯ãã¯ã¼ã«ã¼ã® terminate
ã¡ã½ãããå¼ã³åºãã¦ãã ããã
ã¯ã¼ã«ã¼ã¹ã¬ããã¯ç´ã¡ã«çµäºãã¾ãã
ã¨ã©ã¼å¦çã¯ã¼ã«ã¼å
ã§å®è¡æã¨ã©ã¼ãçºçããã¨ã onerror
ã¤ãã³ããã³ãã©ã¼ãå¼ã³åºããã¾ãããã㯠error
ã¨ããååã®ã¤ãã³ããåãåãã¾ããããã㯠ErrorEvent
ã¤ã³ã¿ã¼ãã§ã¤ã¹ãå®è£
ãã¦ãã¾ãã
ã¤ãã³ãã¯ãããªã³ã°ãããã¾ããã£ã³ã»ã«ãããã¨ãã§ãã¾ããã¯ã¼ã«ã¼ã¯ã¨ã©ã¼ã¤ãã³ãã® preventDefault()
ã¡ã½ãããå¼ã³åºããã¨ã§ãçºçå
ã®æ¢å®ã®ã¢ã¯ã·ã§ã³ãæå¶ãããã¨ãã§ãã¾ãã
ã¨ã©ã¼ã¤ãã³ãã«ã¯ã以ä¸ã®éè¦ãª 3 ã¤ã®ãã£ã¼ã«ããããã¾ãã
message
人éãèªã¿åããã¨ã©ã¼ã¡ãã»ã¼ã¸ã§ãã
filename
ã¨ã©ã¼ãçºçããã¹ã¯ãªããã®ãã¡ã¤ã«åã§ãã
lineno
ã¹ã¯ãªãããã¡ã¤ã«å ã§ã¨ã©ã¼ãçºçããå ´æã®è¡çªå·ã§ãã
ã¯ã¼ã«ã¼ã¯ãå¿ è¦ã«å¿ãã¦ããã«å¤ãã®ã¯ã¼ã«ã¼ãçã¿åºããã¨ãã§ãã¾ãããããããµãã¯ã¼ã«ã¼ã¯ã親ãã¼ã¸ã¨åããªãªã¸ã³å ã§ãã¹ãããã¦ããªããã°ãªãã¾ãããã¾ãããµãã¯ã¼ã«ã¼ã® URI ã¯ã親ãã¼ã¸ã®ãã®ã§ã¯ãªãã親ã¯ã¼ã«ã¼ã®ä½ç½®ãåºæºã«è§£æ±ºããã¾ããããã«ãããã¯ã¼ã«ã¼ã¯èªåã®ä¾åé¢ä¿ãã©ãã«ããããç°¡åã«ææ¡ãããã¨ãã§ãã¾ãã
ã¹ã¯ãªãããã©ã¤ãã©ãªã¼ã®ã¤ã³ãã¼ãã¯ã¼ã«ã¼ã¹ã¬ããã¯ã°ãã¼ãã«é¢æ°ããã¹ã¯ãªãããã¤ã³ãã¼ãããããã® importScripts()
ã«ã¢ã¯ã»ã¹ã§ãã¾ããããã¯ã¤ã³ãã¼ããããªã½ã¼ã¹ã® URI ã 0 å以ä¸ã弿°ã¨ãã¦åãå
¥ãã¾ãã以ä¸ã®ä¾ã¯ãã¹ã¦æå¹ã§ãã
importScripts(); /* ä½ãã¤ã³ãã¼ãããªã */
importScripts("foo.js"); /* "foo.js" ãã¤ã³ãã¼ã */
importScripts("foo.js", "bar.js"); /* 2 ã¤ã®ã¹ã¯ãªãããã¤ã³ãã¼ã */
importScripts(
"//example.com/hello.js",
); /* ä»ã®ãªãªã¸ã³ã®ã¹ã¯ãªãããã¤ã³ãã¼ããããã¨ãã§ãã */
ãã©ã¦ã¶ã¼ã¯ããããã®ã¹ã¯ãªãããèªã¿è¾¼ã¿ãå®è¡ãã¾ããã¯ã¼ã«ã¼ã¯åã¹ã¯ãªããã®ã°ãã¼ãã«ãªãã¸ã§ã¯ãã使ç¨ã§ãã¾ããã¹ã¯ãªãããèªã¿è¾¼ããã¨ãã§ããªãå ´å㯠NETWORK_ERROR
ãçºçããã¦ããã以éã®ã³ã¼ããå®è¡ãã¾ãããããã§ãããã§ã«å®è¡ãããã³ã¼ãï¼setTimeout()
ã§ç¹°ãå»¶ã¹ããã¦ããã³ã¼ããå«ã¿ã¾ãï¼ã¯åä½ãã¾ããimportScripts()
ã¡ã½ãããã徿¹ã«ãã颿°ã®å®£è¨ã¯ã常ã«ã³ã¼ãã®æ®ãã®é¨åããå
ã«è©ä¾¡ããããã¨ãããåæ§ã«ä¿æããã¾ãã
ã¡ã¢: ã¹ã¯ãªããã¯é ä¸åã«ãã¦ã³ãã¼ãããããã¨ãããã¾ãããå®è¡ã¯ importScripts()
ã«æ¸¡ãããã¡ã¤ã«åã®é ã«è¡ãã¾ããããã¯åæçã«è¡ããã¾ãããã¹ã¦ã®ã¹ã¯ãªããã®èªã¿è¾¼ã¿ã¨å®è¡ãè¡ãããã¾ã§ importScripts()
ããæ»ãã¾ããã
å ±æã¯ã¼ã«ã¼ã¯ããªãªã¸ã³ãåä¸ã§ããã°ï¼ç°ãªãã¦ã£ã³ãã¦ãiframeãã¯ã¼ã«ã¼ããã§ãã£ã¦ãï¼è¤æ°ã®ã¹ã¯ãªããããã¢ã¯ã»ã¹ã§ãã¾ããæ¬ç« ã§ã¯åºæ¬çãªå ±æã¯ã¼ã«ã¼ã®ä¾ ã® JavaScript ãè¦ã¦ããã¾ã (å ±æã¯ã¼ã«ã¼ãå®è¡ãã)ããã¡ãã¯å°ç¨ã¯ã¼ã«ã¼ã®ãµã³ãã«ã¨ä¼¼ã¦ãã¾ããã2 ã¤ã®æ°å¤ã§ä¹ç®ãè¡ãã¹ã¯ãªããã¨æ°å¤ã 2 ä¹ããã¹ã¯ãªããã¨ãããå¥ã ã®ã¹ã¯ãªãããã¡ã¤ã«ãæ±ã 2 ã¤ã®é¢æ°ã使ç¨ã§ããç¹ãç°ãªãã¾ããã©ã¡ãã®ã¹ã¯ãªãããåãã¯ã¼ã«ã¼ã使ç¨ãã¦ãå®éã«å¿ è¦ãªè¨ç®ãè¡ãã¾ãã
ããã§ã¯ã å°ç¨ã¯ã¼ã«ã¼ã¨å ±æã¯ã¼ã«ã¼ã®éãã«ã¤ãã¦æ³¨ç®ãã¾ãããã®ä¾ã§ã¯ 2 ã¤ã® HTML ãã¼ã¸ããããããããã® JavaScript ã¯åãåä¸ã®ã¯ã¼ã«ã¼ãã¡ã¤ã«ã使ç¨ããããã«ãªã£ã¦ãã¾ãã
ã¡ã¢: å ±æã¯ã¼ã«ã¼ãè¤æ°ã®é²è¦§ã³ã³ããã¹ãããã¢ã¯ã»ã¹ã§ããå ´åããã¹ã¦ã®é²è¦§ã³ã³ããã¹ãã¯ã¾ã£ããåããªãªã¸ã³ (ãããã³ã«ããã¹ãããã¼ãçªå·ãåã) ã«ãªãã¾ãã
ã¡ã¢: Firefox ã§ã¯ãå ±æã¯ã¼ã«ã¼ã¯ãã©ã¤ãã¼ãã¦ã£ã³ãã¦ã¨ãã以å¤ã«èªã¿è¾¼ã¾ããææ¸éã§å ±æãããã¨ãã§ãã¾ãã (Firefox ãã° 1177621)ã
å ±æã¯ã¼ã«ã¼ã®çææ°ããå ±æã¯ã¼ã«ã¼ã®çææ¹æ³ã¯ å°ç¨ã¯ã¼ã«ã¼ ã®å ´åã¨ã»ã¨ãã©åãã§ãããã³ã³ã¹ãã©ã¯ã¿ã¼åãç°ãªãã¾ãï¼index.html ããã³ index2.html ãã覧ãã ããï¼ãããããã®ãã¼ã¸ã§ã以ä¸ã®ãããªã³ã¼ãã使ç¨ãã¦ã¯ã¼ã«ã¼ãç«ã¡ä¸ãã¾ãã
const myWorker = new SharedWorker("worker.js");
å
±æã¯ã¼ã«ã¼ã®å¤§ããªéãã®ã²ã¨ã¤ãã port
ãªãã¸ã§ã¯ããéãã¦éä¿¡ããªããã°ãªããªããã¨ã§ããã¹ã¯ãªãããã¯ã¼ã«ã¼ã¨éä¿¡ããããã«ä½¿ç¨ã§ãããæç¤ºçãªãã¼ããéãã¾ã (ããã¯ã å°ç¨ã¯ã¼ã«ã¼ã§ãæé»çã«éãã¦ãã¾ã)ã
ãã¼ãã¸ã®æ¥ç¶ã¯ãã¡ãã»ã¼ã¸ãéä¿¡ããåã« onmessage
ã¤ãã³ããã³ãã©ã¼ã使ç¨ãã¦æé»çã«è¡ãããããã㯠start()
ã¡ã½ããã使ç¨ãã¦æç¤ºçã«éå§ãããããªããã°ãªãã¾ããã start()
ã®å¼ã³åºãã¯ãaddEventListener()
ã¡ã½ããã§ message
ã¤ãã³ããæ¾ãä¸ããå ´åã«ã®ã¿å¿
è¦ã§ãã
ã¡ã¢: ãã¼ãæ¥ç¶ãéå§ããããã« start()
ã¡ã½ããã使ç¨ããã¨ããåæ¹åã®éä¿¡ãå¿
è¦ã§ããå ´åã¯è¦ªã¹ã¬ããã¨ã¯ã¼ã«ã¼ã®ä¸¡æ¹ã§å¼ã³åºããªããã°ãªãã¾ããã
åè¿°ã®ã¨ããã¯ã¼ã«ã¼ã«ã¡ãã»ã¼ã¸ãéä¿¡ã§ããããã«ãªãã¾ããããpostMessage()
ã¡ã½ãã㯠port ãªãã¸ã§ã¯ããéãã¦å¼ã³åºããªããã°ãªãã¾ããï¼ç¹°ãè¿ãã¾ãããåæ§ã®æ§é ã multiply.js ããã³ square.js ã«åå¨ãã¾ãï¼ã
squareNumber.onchange = () => {
myWorker.port.postMessage([squareNumber.value, squareNumber.value]);
console.log("ã¡ãã»ã¼ã¸ãã¯ã¼ã«ã¼ã«æ¸¡ããã¾ããã");
};
ã¯ã¼ã«ã¼ã«ç§»ãã¾ãããã¡ãã¯è¥å¹²è¤éããå¢ãã¦ãã¾ã (worker.js):
onconnect = (e) => {
const port = e.ports[0];
port.onmessage = (e) => {
const workerResult = `Result: ${e.data[0] * e.data[1]}`;
port.postMessage(workerResult);
};
};
å§ãã«ããã¼ãã¸ã®æ¥ç¶ãçºçããã¨ãï¼ããªãã¡ã親ã¹ã¬ããã§ onmessage
ã¤ãã³ããã»ããã¢ããããã¨ãã親ã¹ã¬ããã§ start()
ã¡ã½ãããæç¤ºçã«å¼ã³åºããã¨ãï¼ã«ã³ã¼ããå®è¡ãããã onconnect
ãã³ãã©ã¼ã使ç¨ãã¾ãã
ã¤ãã³ããªãã¸ã§ã¯ãã® ports
屿§ã使ç¨ãã¦ãã¼ããåãåºãã夿°ã«æ ¼ç´ãã¾ãã
次ã«ãè¨ç®ãå®è¡ãã¦çµæãã¡ã¤ã³ã¹ã¬ããã«è¿ãããããã¼ãã® onmessage
ã®ãã³ãã©ã¼ã使ç¨ãã¾ããã¯ã¼ã«ã¼ã¹ã¬ããã§ onmessage
ã®ãã³ãã©ã¼ãã»ããã¢ããããã¨ã親ã¹ã¬ããã«æ»ããã¼ãæ¥ç¶ãæé»çã«éãã¾ããå¾ã£ã¦ãå®éã¯åè¿°ã®ã¨ãã port.start()
ãå¼ã³åºãå¿
è¦ã¯ããã¾ããã
æå¾ã«ãã¡ã¤ã³ã¹ã¬ããã«æ»ã£ã¦ã¡ãã»ã¼ã¸ãæ±ãã¾ãï¼ç¹°ãè¿ãã¾ãããåæ§ã®æ§é ã multiply.js ããã³ square.js ã«åå¨ãã¾ãï¼ã
myWorker.port.onmessage = (e) => {
result2.textContent = e.data;
console.log("ã¡ãã»ã¼ã¸ãã¯ã¼ã«ã¼ããåä¿¡ãã¾ãã");
};
ãã¼ããéãã¦ã¯ã¼ã«ã¼ããã¡ãã»ã¼ã¸ãæ»ã£ãã¨ãã¯ãçµæã®ãã¼ã¿åã確èªãã¦ããé©åãªæ®µè½ã«è¨ç®çµæãæ¿å ¥ãã¾ãã
ã¹ã¬ããã»ã¼ãã«ã¤ãã¦Worker
ã¤ã³ã¿ã¼ãã§ã¤ã¹ã§ã¯ãOS ã¬ãã«ã®å®éã®ã¹ã¬ãããçæããããããæ³¨ææ·±ãããã°ã©ãã¼ã¯ã注æããªãã¨åæå®è¡ã«ãã£ã¦ã³ã¼ãã«ãé¢ç½ãã广ãçããã®ã§ã¯ãªããã¨æ¸å¿µããããããã¾ããã
ããããã¦ã§ãã¯ã¼ã«ã¼ã¯ä»ã®ã¹ã¬ããã¨ã®éä¿¡ãã¤ã³ããæ éã«å¶å¾¡ããã¦ãããããåæå®è¡ã®åé¡ãå¼ãèµ·ãããã¨ã¯å®éã«ã¯é常ã«å°é£ã§ããã¹ã¬ããã»ã¼ãã§ãªãã³ã³ãã¼ãã³ãã DOM ã«ã¯ã¢ã¯ã»ã¹ã§ãã¾ãããã¾ããã·ãªã¢ã«åããããªãã¸ã§ã¯ããéãã¦ç¹å®ã®ãã¼ã¿ãã¹ã¬ããã«åºãå ¥ãããªããã°ãªãã¾ãããã§ããããã³ã¼ãã§åé¡ãèµ·ããããã«ã¯ãããªãé£ããã®ã§ãã
ã³ã³ãã³ãã»ãã¥ãªãã£ããªã·ã¼ã¯ã¼ã«ã¼ã¯ãèªåãçæããææ¸ããåºå¥ãããç¬èªã®å®è¡ã³ã³ããã¹ããæã£ã¦ããã¨ã¿ãªããã¾ãããã®ãããä¸è¬ã«ãèªåãçæããææ¸ï¼ã¾ãã¯è¦ªã¯ã¼ã«ã¼ï¼ã®ã³ã³ãã³ãã»ãã¥ãªãã£ããªã·ã¼ã§ã¯ç®¡çããã¾ããããã®ããä¾ãã°ãææ¸ãæ¬¡ã®ãããã¼ä»ãã§èªã¿è¾¼ã¾ããã¨ä»®å®ãã¾ãã
Content-Security-Policy: script-src 'self'
ç¹ã«ããã㯠eval()
ã使ç¨ããã¹ã¯ãªãããé²ãã¾ããããããã¹ã¯ãªãããã¯ã¼ã«ã¼ãæ§ç¯ããå ´åãã¯ã¼ã«ã¼ã®ã³ã³ããã¹ãã§å®è¡ä¸ã®ã³ã¼ã㯠eval()
ã使ç¨ãããã¨ãã§ãã¾ãã
ã¯ã¼ã«ã¼ã®ã³ã³ãã³ãã»ãã¥ãªãã£ããªã·ã¼ãæå®ããã«ã¯ãã¯ã¼ã«ã¼ã¹ã¯ãªããèªèº«ãé ä¿¡ããããªã¯ã¨ã¹ãã® Content-Security-Policy ã¬ã¹ãã³ã¹ãããã¼ã§è¨å®ãã¦ãã ããã
ã¯ã¼ã«ã¼ã¹ã¯ãªããã®ãªãªã¸ã³ãã°ãã¼ãã«ã«ä¸æãªèå¥åã§ããå ´åï¼ä¾ãã°ã URL ã®ã¹ãã¼ã ã data ã blob ã§ãã£ãå ´åï¼ã¯ä¾å¤ã§ãããã®å ´åãã¯ã¼ã«ã¼ã¯ææ¸ã® CSP ã¾ãã¯ããã使ããã¯ã¼ã«ã¼ãç¶æ¿ãã¾ãã
ã¯ã¼ã«ã¼ã¨ã®ãã¼ã¿è»¢éã®è©³ç´°ã¡ã¤ã³ãã¼ã¸ã¨ã¯ã¼ã«ã¼ã®éã§æ¸¡ããããã¼ã¿ã¯ãå ±æã§ã¯ãªãã³ãã¼ããã¾ãããªãã¸ã§ã¯ãã¯ãã¯ã¼ã«ã¼ã«æ¸¡ãããã¨ãã«ã·ãªã¢ã©ã¤ãºããããã®å¾ãå対å´ã§ã·ãªã¢ã©ã¤ãºãè§£é¤ããã¾ãããã¼ã¸ã¨ã¯ã¼ã«ã¼ã¯åãã¤ã³ã¹ã¿ã³ã¹ãå ±æããªããããæçµçã«ã¯ä¸¡å´ã«è¤è£½ã使ããã¾ããã»ã¨ãã©ã®ãã©ã¦ã¶ã¼ã¯ãã®æ©è½ãæ§é åè¤è£½ã¨ãã¦å®è£ ãã¦ãã¾ãã
ããã説æãããããæè²çãªç¨éã®é¢æ° emulateMessage()
ã使ãã worker
ããã¡ã¤ã³ãã¼ã¸ããã³ãã®éã®ç§»åã«ããã¦å
±æãããè¤è£½ãããå¤ã®åä½ãã·ãã¥ã¬ã¼ã·ã§ã³ãã¦ã¿ã¾ãããã
function emulateMessage(vVal) {
return eval(`(${JSON.stringify(vVal)})`);
}
// ãã¹ã
// ãã¹ã #1
const example1 = new Number(3);
console.log(typeof example1); // object
console.log(typeof emulateMessage(example1)); // number
// ãã¹ã #2
const example2 = true;
console.log(typeof example2); // boolean
console.log(typeof emulateMessage(example2)); // boolean
// ãã¹ã #3
const example3 = new String("Hello World");
console.log(typeof example3); // object
console.log(typeof emulateMessage(example3)); // string
// ãã¹ã #4
const example4 = {
name: "Carina Anand",
age: 43,
};
console.log(typeof example4); // object
console.log(typeof emulateMessage(example4)); // object
// ãã¹ã #5
function Animal(type, age) {
this.type = type;
this.age = age;
}
const example5 = new Animal("Cat", 3);
alert(example5.constructor); // Animal
alert(emulateMessage(example5).constructor); // Object
è¤è£½ãããå
±æãããªãå¤ãã¡ãã»ã¼ã¸ã¨å¼ã³ã¾ãããããåããã ã¨æãã¾ãããã¡ãã»ã¼ã¸ã¯ postMessage()
ã使ã£ã¦ã¡ã¤ã³ã¹ã¬ããã¨ã®éã§éåä¿¡ãããã¨ãã§ãã message
ã¤ãã³ãã® data
屿§ã«ã¯ãã¯ã¼ã«ã¼ããè¿ããããã¼ã¿ãå«ã¾ãã¦ãã¾ãã
example.html ï¼ã¡ã¤ã³ãã¼ã¸ï¼
const myWorker = new Worker("my_task.js");
myWorker.onmessage = (event) => {
console.log(`Worker said : ${event.data}`);
};
myWorker.postMessage("ali");
my_task.js ï¼ã¯ã¼ã«ã¼ï¼
postMessage("I'm working before postMessage('ali').");
onmessage = (event) => {
postMessage(`Hi, ${event.data}`);
};
æ§é åè¤è£½ã¢ã«ã´ãªãºã 㯠JSON ãåãå ¥ãããã¨ãã§ãã循ç°åç §ãªã© JSON ã§ã¯ã§ããªããã®ãããã¤ãåãå ¥ãããã¨ãã§ãã¾ãã
ãã¼ã¿å¼ã渡ãã®ä¾ ä¾ 1: é«åº¦ãª JSON ãã¼ã¿æ¸¡ãã¨åãæ¿ãã·ã¹ãã ã®ä½æããããã¤ãã®è¤éãªãã¼ã¿ã渡ããªããã°ãªãããã¡ã¤ã³ãã¼ã¸ã¨ã¯ã¼ã«ã¼ã®ä¸¡æ¹ã§å¤ãã®ç°ãªã颿°ãå¼ã³åºããªããã°ãªããªãå ´åããã¹ã¦ãã¾ã¨ãã¦ã°ã«ã¼ãã«ããã·ã¹ãã ãä½ããã¨ãã§ãã¾ãã
ã¯ããã«ãã¯ã¼ã«ã¼ã® URLãæ¢å®ã®ãªã¹ãã¼ãã¨ã©ã¼ãã³ãã©ã¼ãæã¤ QueryableWorker
ã¯ã©ã¹ãä½ãã¾ãããã®ã¯ã©ã¹ã¯ãªã¹ãã¼ã®ãªã¹ããè¨é²ããã¯ã¼ã«ã¼ã¨ã®ã³ãã¥ãã±ã¼ã·ã§ã³ã«å½¹ç«ã¦ã¾ãã
function QueryableWorker(url, defaultListener, onError) {
const worker = new Worker(url);
const listeners = {};
this.defaultListener = defaultListener ?? (() => {});
if (onError) {
worker.onerror = onError;
}
this.postMessage = (message) => {
worker.postMessage(message);
};
this.terminate = () => {
worker.terminate();
};
}
ããã¦ããªã¹ãã¼ã追å /åé¤ããã¡ã½ããã追å ãã¾ãã
this.addListeners = (name, listener) => {
listeners[name] = listener;
};
this.removeListeners = (name) => {
delete listeners[name];
};
ããã§ã¯ã説æã®ããã«ã¯ã¼ã«ã¼ã« 2 ã¤ã®ç°¡åãªæä½ãããã¦ã¿ã¾ãããã 2 ã¤ã®æ°å¤ã®å·®ãåå¾ãããã¨ã¨ã 3 ç§å¾ã«ã¢ã©ã¼ããåºããã¨ã§ãããããå®ç¾ããããã«ãã¾ãæåã« sendQuery
ã¡ã½ãããå®è£
ãã¾ããããã¯ãã¯ã¼ã«ã¼ãå®éã«å¯¾å¿ããã¡ã½ãããæã£ã¦ãããã©ãããåãåããããã®ã§ãã
// This functions takes at least one argument, the method name we want to query.
// Then we can pass in the arguments that the method needs.
this.sendQuery = (queryMethod, ...queryMethodArguments) => {
if (!queryMethod) {
throw new TypeError(
"QueryableWorker.sendQuery 㯠1 ã¤ä»¥ä¸ã®å¼æ°ãå¿
è¦ã§ã",
);
}
worker.postMessage({
queryMethod,
queryMethodArguments,
});
};
QueryableWorker ã onmessage
ã¡ã½ããã§çµäºããã¾ããåãåãããã¡ã½ããã«å¯¾å¿ããã¯ã¼ã«ã¼ãããã°ã対å¿ãããªã¹ãã¼ã®ååã¨å¿
è¦ãªå¼æ°ãè¿ãã¦ãããã¯ããªã®ã§ããã¨ã¯ listeners
ã®ä¸ãæ¢ãã ãã§ãã
worker.onmessage = (event) => {
if (
event.data instanceof Object &&
Object.hasOwn(event.data, "queryMethodListener") &&
Object.hasOwn(event.data, "queryMethodArguments")
) {
listeners[event.data.queryMethodListener].apply(
instance,
event.data.queryMethodArguments,
);
} else {
this.defaultListener.call(instance, event.data);
}
};
次ã«ã¯ã¼ã«ã¼ã§ããã¾ãã 2 ã¤ã®ç°¡åãªæä½ãè¡ãããã®ã¡ã½ãããå¿ è¦ã§ãã
const queryableFunctions = {
getDifference(a, b) {
reply("printStuff", a - b);
},
waitSomeTime() {
setTimeout(() => {
reply("doAlert", 3, "seconds");
}, 3000);
},
};
function reply(queryMethodListener, ...queryMethodArguments) {
if (!queryMethodListener) {
throw new TypeError("reply - takes at least one argument");
}
postMessage({
queryMethodListener,
queryMethodArguments,
});
}
// This method is called when main page calls QueryWorker's postMessage
// method directly
function defaultReply(message) {
// do something
}
ããã¦ãonmessage
ã¡ã½ããã¯ç°¡åã«ãªãã¾ããã
onmessage = (event) => {
if (
event.data instanceof Object &&
Object.hasOwn(event.data, "queryMethod") &&
Object.hasOwn(event.data, "queryMethodArguments")
) {
queryableFunctions[event.data.queryMethod].apply(
self,
event.data.queryMethodArguments,
);
} else {
defaultReply(event.data);
}
};
ããã§ã¯ãå®å ¨ãªå®è£ ãç´¹ä»ãã¾ãã
example.html ï¼ã¡ã¤ã³ãã¼ã¸ï¼
<!doctype html>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>MDN Example - Queryable worker</title>
<script>
// QueryableWorker instances methods:
// * sendQuery(queryable function name, argument to pass 1, argument to pass 2, etc. etc.): calls a Worker's queryable function
// * postMessage(string or JSON Data): see Worker.prototype.postMessage()
// * terminate(): terminates the Worker
// * addListener(name, function): adds a listener
// * removeListener(name): removes a listener
// QueryableWorker instances properties:
// * defaultListener: the default listener executed only when the Worker calls the postMessage() function directly
function QueryableWorker(url, defaultListener, onError) {
const instance = this;
const worker = new Worker(url);
const listeners = {};
this.defaultListener = defaultListener ?? (() => {});
if (onError) {
worker.onerror = onError;
}
this.postMessage = (message) => {
worker.postMessage(message);
};
this.terminate = () => {
worker.terminate();
};
this.addListener = (name, listener) => {
listeners[name] = listener;
};
this.removeListener = (name) => {
delete listeners[name];
};
// This functions takes at least one argument, the method name we want to query.
// Then we can pass in the arguments that the method needs.
this.sendQuery = (queryMethod, ...queryMethodArguments) => {
if (!queryMethod) {
throw new TypeError(
"QueryableWorker.sendQuery takes at least one argument",
);
}
worker.postMessage({
queryMethod,
queryMethodArguments,
});
};
worker.onmessage = (event) => {
if (
event.data instanceof Object &&
Object.hasOwn(event.data, "queryMethodListener") &&
Object.hasOwn(event.data, "queryMethodArguments")
) {
listeners[event.data.queryMethodListener].apply(
instance,
event.data.queryMethodArguments,
);
} else {
this.defaultListener.call(instance, event.data);
}
};
}
// ç¬èªã®ãç
§ä¼å¯è½ãªãã¯ã¼ã«ã¼
const myTask = new QueryableWorker("my_task.js");
// ç¬èªã®ããªã¹ãã¼ã
myTask.addListener("printStuff", (result) => {
document
.getElementById("firstLink")
.parentNode.appendChild(
document.createTextNode(`The difference is ${result}!`),
);
});
myTask.addListener("doAlert", (time, unit) => {
alert(`Worker waited for ${time} ${unit} :-)`);
});
</script>
</head>
<body>
<ul>
<li>
<a
id="firstLink"
href="javascript:myTask.sendQuery('getDifference', 5, 3);"
>What is the difference between 5 and 3?</a
>
</li>
<li>
<a href="javascript:myTask.sendQuery('waitSomeTime');"
>Wait 3 seconds</a
>
</li>
<li>
<a href="javascript:myTask.terminate();">terminate() the Worker</a>
</li>
</ul>
</body>
</html>
my_task.js ï¼ã¯ã¼ã«ã¼ï¼
const queryableFunctions = {
// ä¾ #1: 2 ã¤ã®å¤ã®å·®ãå¾ã
getDifference(minuend, subtrahend) {
reply("printStuff", minuend - subtrahend);
},
// ä¾ #2: 3 ç§å¾
ã¤
waitSomeTime() {
setTimeout(() => {
reply("doAlert", 3, "seconds");
}, 3000);
},
};
// ã·ã¹ãã 颿°
function defaultReply(message) {
// ã¡ã¤ã³ãã¼ã¸ã queryableWorker.postMessage() ã¡ã½ãããç´æ¥å¼ã³åºããã¨ãã«éãå®è¡ããããããã©ã«ãã® PUBLIC 颿°
// ä½ããã®å¦ç
}
function reply(queryMethodListener, ...queryMethodArguments) {
if (!queryMethodListener) {
throw new TypeError("reply - not enough arguments");
}
postMessage({
queryMethodListener,
queryMethodArguments,
});
}
onmessage = (event) => {
if (
event.data instanceof Object &&
Object.hasOwn(event.data, "queryMethod") &&
Object.hasOwn(event.data, "queryMethodArguments")
) {
queryableFunctions[event.data.queryMethod].apply(
self,
event.data.queryMethodArguments,
);
} else {
defaultReply(event.data);
}
};
åã¡ã¤ã³ãã¼ã¸ â ã¯ã¼ã«ã¼ãã¯ã¼ã«ã¼ â ã¡ã¤ã³ãã¼ã¸ã¨ã¡ãã»ã¼ã¸ã®å
容ãåãæ¿ãããã¨ãã§ãã¾ããããã¦ã "queryMethod", "queryMethodListeners", "queryMethodArguments" ã®åããããã£åã¯ã QueryableWorker
ã¨ã¯ã¼ã«ã¼ã§ä¸è´ãã¦ããã°ä½ã§ãæ§ãã¾ããã
ç¾ä»£ã®ãã©ã¦ã¶ã¼ã«ã¯ããã種ã®ãªãã¸ã§ã¯ããã¯ã¼ã«ã¼ã«ãã¾ãã¯ã¯ã¼ã«ã¼ããé«ãããã©ã¼ãã³ã¹ã§æ¸¡ãããã®å¥ã®æ¹æ³ãããã¾ããç§»è²å¯è½ãªãã¸ã§ã¯ãã¯ãããã³ã³ããã¹ãããå¥ã®ã³ã³ããã¹ãã¸ã¼ãã³ãã¼æ¼ç®ãéå¶ãã¦è»¢éãããã®ã§ã大ããªãã¼ã¿ã»ãããéä¿¡ããã¨ãã«ããã©ã¼ãã³ã¹ãå¤§å¹ ã«æ¹åããã¾ãã
ä¾ãã°ãã¡ã¤ã³ã¢ããªããã¯ã¼ã«ã¼ã¹ã¯ãªããã« ArrayBuffer
ãç§»è²ããå ´åãå
ã® ArrayBuffer
ã¯ã¯ãªã¢ããã¦ãã使ããªããªãã¾ãããã®å
容ã¯ãï¼æåã©ããï¼ã¯ã¼ã«ã¼ã®ã³ã³ããã¹ãã«ç§»è²ããã¾ãã
// 32MB ã®ããã¡ã¤ã«ãã使ãã 0 ãã 255 ã¾ã§ã®é£ç¶ããå¤ã§åãã¾ãã â 32MB = 1024 * 1024 * 32
const uInt8Array = new Uint8Array(1024 * 1024 * 32).map((v, i) => i);
worker.postMessage(uInt8Array.buffer, [uInt8Array.buffer]);
åãè¾¼ã¿ã¯ã¼ã«ã¼
ã¯ã¼ã«ã¼ã®ã³ã¼ããã¦ã§ããã¼ã¸ã«åãè¾¼ãããã®ãé常ã®ã¹ã¯ãªããã <script>
è¦ç´ ã§åãè¾¼ããããªãå
¬å¼ãªãæ¹æ³ã¯ããã¾ããããããã<script>
è¦ç´ ã src
屿§ãæãããã¾ã type
屿§ãå®è¡å¯è½ãª MIME ã¿ã¤ãã示ãã¦ããªãå ´åã¯ã JavaScript ã使ç¨ã§ãããã¼ã¿ãããã¯è¦ç´ ã§ããã¨å¤æããã¾ããããã¼ã¿ãããã¯ãã¯ã»ã¨ãã©ã®ããã¹ããã¼ã¿ãæã¤ãã¨ãã§ããã HTML ã®ä¸è¬çãªæ©è½ã§ãããã£ã¦ã以ä¸ã®æ¹æ³ã§ã¯ã¼ã«ã¼ãåãè¾¼ããã¨ãã§ãã¾ãã
<!doctype html>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<title>MDN Example - Embedded worker</title>
<script type="text/js-worker">
// MIME ã¿ã¤ãã text/js-worker ã§ããããããã®ã¹ã¯ãªãã㯠JS ã¨ã³ã¸ã³ã«è§£éããã¾ããã
const myVar = 'Hello World!';
// ã¯ã¼ã«ã¼ã®æ®ãã®ã³ã¼ããããã«ç½®ãã¾ãã
</script>
<script>
// MIME ã¿ã¤ãã text/javascript ã§ããããããã®ã¹ã¯ãªãã㯠JS ã¨ã³ã¸ã³ã«è§£éããã¾ãã
function pageLog(sMsg) {
// ãã©ã°ã¡ã³ãã使ç¨ãã¾ãããã©ã¦ã¶ã¼ã®ã¬ã³ããªã³ã°ãåããã¼ã 1 åã ãã«ãã¾ãã
const frag = document.createDocumentFragment();
frag.appendChild(document.createTextNode(sMsg));
frag.appendChild(document.createElement("br"));
document.querySelector("#logDisplay").appendChild(frag);
}
</script>
<script type="text/js-worker">
// MIME ã¿ã¤ãã text/js-worker ã§ããããããã®ã¹ã¯ãªãã㯠JS ã¨ã³ã¸ã³ã«è§£éããã¾ããã
onmessage = (event) => {
postMessage(myVar);
};
// ã¯ã¼ã«ã¼ã®æ®ãã®ã³ã¼ããããã«ç½®ãã¾ãã
</script>
<script>
// MIME ã¿ã¤ãã text/javascript ã§ããããããã®ã¹ã¯ãªãã㯠JS ã¨ã³ã¸ã³ã«è§£éããã¾ãã
// 以å㯠blob ãæ§ç¯ãã¦ãã¾ããããç¾å¨ã¯ Blob ã使ç¨ãã¾ãã
const blob = new Blob(
Array.prototype.map.call(
document.querySelectorAll("script[type='text/js-worker']"),
(script) => script.textContent,
),
{ type: "text/javascript" },
);
// ãã¹ã¦ã® "text/js-worker" ã¹ã¯ãªãããå«ããæ°ã㪠document.worker ããããã£ãçæãã¾ãã
document.worker = new Worker(window.URL.createObjectURL(blob));
document.worker.onmessage = (event) => {
pageLog(`Received: ${event.data}`);
};
// ã¯ã¼ã«ã¼ãèµ·åãã¾ãã
window.onload = () => {
document.worker.postMessage("");
};
</script>
</head>
<body>
<div id="logDisplay"></div>
</body>
</html>
åãè¾¼ã¿ã¯ã¼ã«ã¼ã¯ãæ°ã㪠document.worker
ã«ã¹ã¿ã ããããã£ã®ä¸ã«å
¥ãã¾ããã
è¨ãã¾ã§ããªããæ¬¡ã®ä¾ã®ããã«ã颿°ã Blob ã«å¤æãã¦ããã® blob ãããªãã¸ã§ã¯ãã® URL ãçæãããã¨ãã§ãã¾ãã
function fn2workerURL(fn) {
const blob = new Blob([`(${fn.toString()})()`], { type: "text/javascript" });
return URL.createObjectURL(blob);
}
追å ã®ä¾
ããã§ã¯ã¦ã§ãã¯ã¼ã«ã¼ã®ä½¿ç¨æ¹æ³ã«ã¤ãã¦ãããã«ä¾ã示ãã¾ãã
ããã¯ã°ã©ã¦ã³ãã§æ¼ç®ãè¡ãã¯ã¼ã«ã¼ã¯ä¸»ã«ãã¦ã¼ã¶ã¼ã¤ã³ã¿ã¼ãã§ã¤ã¹ã®ã¹ã¬ããã妨ããã« CPU è² è·ã大ããæ¼ç®ãå®è¡ããããã«å½¹ç«ã¡ã¾ãããã®ãµã³ãã«ã§ã¯ãã¯ã¼ã«ã¼ããã£ããããæ°ã®è¨ç®ã«ä½¿ç¨ãã¾ãã
JavaScript ã³ã¼ã以ä¸ã® JavaScript ã³ã¼ãããã¡ã¤ã« "fibonacci.js" ã«ä¿åããæ¬¡ç¯ã® HTML ããåç §ãã¾ãã
self.onmessage = (event) => {
const userNum = Number(event.data);
self.postMessage(fibonacci(userNum));
};
function fibonacci(num) {
let a = 1;
let b = 0;
while (num > 0) {
[a, b] = [a + b, a];
num--;
}
return b;
}
ã¯ã¼ã«ã¼ã¯ onmessage
ããããã£ããã¯ã¼ã«ã¼ã®ãªãã¸ã§ã¯ãã® postMessage()
ãå¼ã³åºãããã¨ãã«ã¡ãã»ã¼ã¸ãåãåã颿°ã«è¨å®ãã¾ããããã¯è¨ç®ãå®è¡ããæçµçã«çµæãã¡ã¤ã³ã¹ã¬ããã«è¿ãã¾ãã
<!doctype html>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<title>Fibonacci number generator</title>
<style>
body {
width: 500px;
}
div,
p {
margin-bottom: 20px;
}
</style>
</head>
<body>
<form>
<div>
<label for="number"
>Enter a number that is a zero-based index position in the fibonacci
sequence to see what number is in that position. For example, enter 6
and you'll get a result of 8 â the fibonacci number at index position
6 is 8.</label
>
<input type="number" id="number" />
</div>
<div>
<input type="submit" />
</div>
</form>
<p id="result"></p>
<script>
const form = document.querySelector("form");
const input = document.querySelector('input[type="number"]');
const result = document.querySelector("p#result");
const worker = new Worker("fibonacci.js");
worker.onmessage = (event) => {
result.textContent = event.data;
console.log(`Got: ${event.data}`);
};
worker.onerror = (error) => {
console.log(`Worker error: ${error.message}`);
throw error;
};
form.onsubmit = (e) => {
e.preventDefault();
worker.postMessage(input.value);
input.value = "";
};
</script>
</body>
</html>
ã¦ã§ããã¼ã¸ã¯ result
ã¨ãã ID ãæã¤ <p>
è¦ç´ ã使ãã¦ãçµæã表示ããããã«ä½¿ç¨ãã¾ããããã¦ãã¯ã¼ã«ã¼ãèµ·åãã¾ããã¯ã¼ã«ã¼ãèµ·åããå¾ã¯ãonmessage
ãã³ãã©ã¼ã <p>
è¦ç´ ã®å
容ãè¨å®ãããã¨ã§çµæã表示ããããã«æ§æããã¾ã onerror
ãã³ãã©ã¼ã¯ã¨ã©ã¼ã¡ãã»ã¼ã¸ãéçºè
ãã¼ã«ã®ã³ã³ã½ã¼ã«ã¸è¨é²ããããã«è¨å®ãã¾ãã
æå¾ã«ãã¯ã¼ã«ã¼ãéå§ããããã«ã¡ãã»ã¼ã¸ãéä¿¡ãã¾ãã
ãã®ä¾ã®ãã¢ã試ãã¦ãã ããã
è¤æ°ã®ã¯ã¼ã«ã¼ã«ã¿ã¹ã¯ãåå²ãããã«ãã³ã¢ã®ã³ã³ãã¥ã¼ã¿ã¼ãä¸è¬çã«ãªã£ã¦ãããã¨ã§è¤æ°ã®ã¯ã¼ã«ã¼ã«è¤éãªè¨ç®å¦çãåå²ãããã¨ãæç¨ã«ãªãããããã®ã¿ã¹ã¯ãè¤æ°ã® CPU ã³ã¢ã§å®è¡ãããã¨ãå¯è½ã«ãªãã¾ãã
ãã®ä»ã®ã¯ã¼ã«ã¼å°ç¨ã¯ã¼ã«ã¼ãå ±æã¯ã¼ã«ã¼ã«å ãã¦ãå©ç¨ã§ããä»ã®ç¨®é¡ã®ã¯ã¼ã«ã¼ãããã¾ãã
ã»ã¨ãã©ã®ãã©ã¦ã¶ã¼ã¯ã JavaScript ãããã¬ã¼ã§ã¯ã¼ã«ã¼ã¹ã¬ããã®ãããã°ããã¡ã¤ã³ã¹ã¬ããã®ãããã°ã¨ã¾ã£ããåãæ¹æ³ã§å¯¾å¿ãã¦ãã¾ãããã¨ãã°ã Firefox 㨠Chrome ã®ä¸¡æ¹ã§ãã¡ã¤ã³ã¹ã¬ããã¨ã¢ã¯ãã£ããªã¯ã¼ã«ã¼ã¹ã¬ããã®ä¸¡æ¹ã® JavaScript ã½ã¼ã¹ãã¡ã¤ã«ãä¸è¦§è¡¨ç¤ºãããããã®ãã¡ã¤ã«ããã¹ã¦éãã¦ãã¬ã¼ã¯ãã¤ã³ãããã°ãã¤ã³ããè¨å®ãããã¨ãã§ãã¾ãã
ã¦ã§ãã¯ã¼ã«ã¼ããããã°ããæ¹æ³ã«ã¤ãã¦ã¯ãåãã©ã¦ã¶ã¼ã® JavaScript ãããã¬ã¼ã®ããã¥ã¡ã³ããåç §ãã¦ãã ããã
ã¦ã§ãã¯ã¼ã«ã¼ç¨ã®éçºè ãã¼ã«ãéãã«ã¯ã次㮠URL ã使ç¨ã§ãã¾ãã
edge://inspect/
chrome://inspect/
about:debugging#/runtime/this-firefox
ãããã®ãã¼ã¸ã«ã¯ããã¹ã¦ã®ãµã¼ãã¹ã¯ã¼ã«ã¼ã®æ¦è¦ã表示ããã¾ããURL ãã該å½ããã¯ã¼ã«ã¼ãè¦ã¤ãã[inspect] ãã¯ãªãã¯ããã¨ããã®ã¯ã¼ã«ã¼ã®ã³ã³ã½ã¼ã«ããããã¬ã¼ãªã©ã®éçºè ãã¼ã«ã«ã¢ã¯ã»ã¹ã§ãã¾ãã
ã¯ã¼ã«ã¼ã§ä½¿ç¨ã§ãã颿°ã¨ã¤ã³ã¿ã¼ãã§ã¤ã¹æ¨æºç㪠JavaScript æ©è½ã®ã»ã¨ãã©ãã¦ã§ãã¯ã¼ã«ã¼å ã§ä½¿ç¨ã§ãã¾ãã以ä¸ã®ãã®ãå«ã¿ã¾ãã
Navigator
fetch()
Array
ãDate
ãMath
ãString
setTimeout()
ããã³ setInterval()
ã¯ã¼ã«ã¼ã§ã§ããªããã¨ã¯ã主ã«è¦ªãã¼ã¸ã«ç´æ¥å½±é¿ãä¸ãããã¨ã§ããä¾ãã°ãDOM ãæä½ãããããã®ãã¼ã¸ã®ãªãã¸ã§ã¯ãã使ç¨ããããããã¨ãªã©ã§ãããã®ãããªæä½ã¯ãDedicatedWorkerGlobalScope.postMessage()
ãä»ãã¦ã¡ã¤ã³ã¹ã¯ãªããã«ã¡ãã»ã¼ã¸ãéä¿¡ããã¤ãã³ããã³ãã©ã¼ã§å¤æ´ãè¡ãã¨ãã£ã鿥çãªæ¹æ³ã§è¡ãå¿
è¦ãããã¾ãã
ã¡ã¢: ããã¡ã½ãããã¯ã¼ã«ã¼ã§å©ç¨ã§ãããã©ããã¯ããµã¤ã https://worker-playground.glitch.me/ ã使ã£ã¦ãã¹ãã§ãã¾ããä¾ãã°ãFirefox 84 ã§ãµã¤ãã« EventSource
ã¨å
¥åããã¨ããµã¼ãã¹ã¯ã¼ã«ã¼ã§ã¯ãµãã¼ãããã¦ããªãããå°ç¨ã¯ã¼ã«ã¼ãå
±æã¯ã¼ã«ã¼ã§ã¯ãµãã¼ãããã¦ãããã¨ããããã¾ãã
ã¡ã¢: ã¯ã¼ã«ã¼ã§ä½¿ç¨ã§ãã颿°ã®å®å ¨ãªãªã¹ãã¯ãã¯ã¼ã«ã¼ã§ä½¿ç¨ã§ãã颿°ã¨ã¤ã³ã¿ã¼ãã§ã¤ã¹ã§ã覧ãã ããã
仿§æ¸ é¢é£æ å ±Worker
ã¤ã³ã¿ã¼ãã§ã¤ã¹SharedWorker
ã¤ã³ã¿ã¼ãã§ã¤ã¹OffscreenCanvas
ã¤ã³ã¿ã¼ãã§ã¤ã¹RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4