I want thread feature when writing JS codes...
from the previous I was wondering if I can not use threads in JS, but I found this article in 2008 a little while ago,
(linked post is Japanese, so please translate with browser feature or something...)
https://www.infoq.com/jp/articles/js_multithread_2/
I thought that this is amazing!
but last commit of implementation placed on SourceForge is 4 years ago...
https://sourceforge.net/projects/jsthread/
so I thought that this should not works, maybe...
Giving it a try
from the Release page of the product,
https://sourceforge.net/projects/jsthread/files/release/
download js files listed below.
- Concurrent.Thread-full-20090713.js
- Concurrent.Thread.ScriptExecuter+Http.js
- Concurrent.Thread.Compiler+Http.js
and write HTML and JS code like below.
then, it worked as multithreaded program correctly!!!
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>jsthread</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script type="text/javascript" src="Concurrent.Thread.Compiler+Http.js">
</script>
<script type="text/javascript" src="Concurrent.Thread.ScriptExecuter+Http.js">
</script>
<script type="text/javascript" src="Concurrent.Thread-full-20090713.js">
</script>
</head>
<body>
<script type = "text/javascript">
function getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max));
};
function f1(){
var i = 0;
while(1){
document.body.innerHTML += i++ + "<br>";
}
};
function f2(){
while(1){
console.log(getRandomInt(1000));
}
};
Concurrent.Thread.create(f1)
Concurrent.Thread.create(f2)
</script>
</body>
</html>
What I implementd at above HTML and JS
- define functions which is executed on each thread
- start two threds
- first thread appends numbers to DOM on endless loop
- second thread outputs random numbers to console on endless loop
if you write an infinite loop that does not end with no thread library, your program would freeze (the UI seems to be freezed), but this code does not.
Demo
I placed above codes at repl.it .
please access and press run button.
https://repl.it/@ryo_grid/ConcurrentThreadtestshareqiita
on web view, incremented numbers is outputted like falls.
on console view, random numbers is outputted like same.
Implementation of coordinated type pseudo thread with async/await and Promise
with Promise, we can write a sleep function which releases thread execution right.
so we can write coordinated type pseudo thread (non preemptive) with async/await by calling the sleep function periodically.
experimental implementation demo is below.
above repl runs two pseudo thread which are context-swiched every 10ms.
each pseudo thread outputs string to console.
script execution finishes when 10sec elapsed (before 10sec, repl.it may stop the script)
in addition, above implementation worked at node.js v10.13.0.
tested code is below.
const sleep = msec => new Promise(resolve => setTimeout(resolve, msec));
function get_unixtime_msec(){
var date = new Date() ;
var cur_date = date.getTime() ;
return cur_date;
}
async function th1(){
var start_time = get_unixtime_msec();
var past_time = get_unixtime_msec();
var cur_time = null;
while(1){
cur_time = get_unixtime_msec()
if(cur_time - past_time >= 10){ // if there is diff longer than 1 sec
if(cur_time - start_time >= 10 * 1000){
// finish this thread if 10sec elapsed
break;
}
await sleep(10);
past_time = get_unixtime_msec();
}
console.log("I am th1!!!");
}
}
async function th2(){
var start_time = get_unixtime_msec();
var past_time = get_unixtime_msec();
var cur_time = null;
while(1){
cur_time = get_unixtime_msec()
if(cur_time - past_time >= 10){ // if there is diff longer than 1 sec
if(cur_time - start_time >= 10 * 1000){
// finish this thread if 10sec elapsed
break;
}
await sleep(10);
past_time = get_unixtime_msec();
}
console.log("I am th2!!!");
}
}
async function exec_two_threads(){
th1();
await th2();
}
function success(result){
console.log("successfully two thread finished.");
}
function failed(error){
console.log(error)
console.log("thread execution is failed.");
}
// get Promise object
var two_thread_promise = exec_two_threads();
// wait finish of two threads
two_thread_promise.then(success, failed);