JavaScript单线程事件循环及多线程实现

2017-12-28  本文已影响0人  环零弦

一、JavaScript的单线程特点

JavaScript最初设计是用来在浏览器中操作DOM的,所以JavaScript的单线程特点也是为了避免多线程时带来的同步问题。

二、JavaScript单线程事件循环

JavaScript单线程事件循环特点如下

三、例子

setTimeout(function () {
  console.log('timeout1');
})

new Promise(function (resolve) {
  console.log('promise1');
  for (var i = 0; i < 1000; i++) {
    i == 99 && resolve();
  }
  console.log('promise2');
}).then(function () {
  console.log('then1');
})

console.log('global1');

上面代码的执行顺序是什么?

1. 代码执行遇到setTimeout,setTimeout为一个宏任务源,那么他的作用就是将任务分发到它对应的队列中。
2. script执行时遇到Promise实例。Promise构造函数中的第一个参数,是在new的时候执行,因此不会进入任何其他的队列,而是直接在当前任务直接执行了,而后续的.then则会被分发到micro-task的Promise队列中去。 因此输出:promise1、promise2。
3. script任务继续往下执行,最后只有一句输出了globa1,然后,全局任务就执行完毕了。
4. 第一个宏任务script执行完毕之后,就开始执行所有的可执行的微任务。这个时候,微任务中,只有Promise队列中的一个任务then1,因此直接执行就行了,执行结果输出then1。
5. 当所有的micro-tast执行完毕之后,表示第一轮的循环就结束了。这个时候就得开始第二轮的循环。第二轮循环仍然从宏任务macro-task开始。这个时候,我们发现宏任务中,只有在setTimeout队列中还要一个timeout1的任务等待执行。因此就直接执行即可。
所以输出是这样的:

promise1
promise2
global1
then1
timeout1

四、JavaScript多线程的实现

test.html

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <title>JavaScript Multiple Processes Test</title>
</head>

<body>
  <input type="text" name="haorooms" id="haorooms" value="" />
  <button id="start">start</button>
  <button id="stop">stop</button>
  <button id="ale">alert</button>
  <script type="text/javascript">
    var haorooms = document.getElementById("haorooms"),
        stop = document.getElementById("stop"),
        start = document.getElementById("start"),
        ale = document.getElementById("ale"),
        worker;
    stop.addEventListener("click", function () {
      //用于关闭worker线程
      worker ? worker.terminate() : {};
    });
    start.addEventListener("click", function () {
      //开起worker线程
      worker = new Worker("test.js");
      worker.onmessage = function () {
        haorooms.value = event.data;
      };
    });
    ale.addEventListener("click", function () {
      alert("i'm a alert worker test");
    });
  </script>
</body>

</html>

test.js

var i = 0;
function mainFunc(){
    i++;
    //把i发送到浏览器的js引擎线程里
    postMessage(i);
}
var id = setInterval(mainFunc,1000);

参考资料

上一篇 下一篇

猜你喜欢

热点阅读