美文网首页
JavaScript单线程及web worker实现多线程

JavaScript单线程及web worker实现多线程

作者: lmmy123 | 来源:发表于2018-10-22 11:45 被阅读3次

一.为什么JavaScript是单线程?

JavaScript是单线程语言,即同一时间只能做一件事(同步)
JavaScript主要用途是用户交互即操作DOM,决定了其只能是单线程,比如说,在一个DOM添加新的内容,并删除这个元素,如果是多线程,那应该先操作哪步,必然会矛盾,单线程则不会,按先后顺序执行

二. 任务队列(异步)

单线程意味着所有的任务都要排队进行,如果碰到耗时长的操作(IO设备,定时器。。),会造成js阻塞,形成页面假死状态,所有采用异步执行:

  • 所有的同步任务都会在主线程上执行,形成执行栈
  • 主线程之外,存在一个"任务队列"(task queue),将异步任务的事件放到任务队列中
  • 执行栈中所有的同步任务执行完毕后, 开始读取任务队列,将任务队列中的事件放到执行栈中执行(先进先出)
  • 重复执行上面三步,这就是js event-loop(事件循环)

web worker 实现多线程

worker 是 H5中引入的实现多线程的方案
先检测你的浏览器是否支持worker

if( window.worker ) { ...code }

实现代码

// main.js  主代码
var worker = new Worker('worker.js') //创建并实例化个对象
worker.postMessage(36) // 发送数据
// 接受返回的数据
worker.onmessage = function(event){
    var data = event.data; // 返回的数据
}
// 报错处理
worker.onerror = function(event){
    console.log(event.filename,event.lineno,evnet.message)
}
worker.terminate() // 自动关闭
// worker.js
// 子线程中不能再调用 new Worker创建新的子线程
// 接收数据
self.onmessage = function(event){
    var data = event.data; // 此处就是从 main.js 传过来的 36
    。。。逻辑处理
    postMessage(newData) // 发送新的数据到 main.js
}
self.close() // 子线程中手动关闭

使用的限制

  • 同源限制
    分配给Worker 线程运行的脚本文件(worker.js),必须与主线程的脚本文件(main.js)同源
  • 访问限制
    Worker子线程所在的全局对象,与主线程不在同一个上下文环境,无法读取主线程所在网页的 DOM 对象, 也无法使用document、window、parent这些对象,global对象的指向有变更,window需要改写成self,不能执行alert()方法和confirm()等方法,只能读取部分navigator对象内的数据。另外chrome的console.log()倒是可以使用,也支持debugger断点,增加调试的便利性。
  • 使用异步
    Worker子线程中可以使用XMLHttpRequest 对象发出 AJAX 请求,可以使用setTimeout() setInterval()方法,也可使用websocket进行持续链接。也可以通过importScripts(url)加载另外的脚本文件,但是仍然不能跨域。

应用场景

1、使用专用线程进行数学运算
2、高频的用户交互
3、数据的预取


参考文献
http://www.ruanyifeng.com/blog/2014/10/event-loop.html
https://juejin.im/post/5bcc1887f265da0aff177227#comment

相关文章

网友评论

      本文标题:JavaScript单线程及web worker实现多线程

      本文链接:https://www.haomeiwen.com/subject/qkgwzftx.html