thread
HTML5多线程(Web Worker)
HTML5标准定义了一套API,允许一段javascript程序运行在主线程以外的另一个线程中。
主线程运行时,Worker子线程在后台运行,互不干扰,将结果返回给主线程。
检测浏览器是否支持Worker:
if (window.Worker) { document.write('worker thread working'); }
主线程:
let worker = new Worker('worker.js');
worker.postMessage('hello world');
worker.onmessage = function(event) {
console.log('received message ' + event.data);
todo();
}
worker.terminate();
worker.addEventListerner('error', function(e) {
console.log('error', e);
});
worker线程:
addEventListerner('message', function(e) {
postMessage('you said: ' + e.data);
}, false);
close();
使用问题:
1.同源限制
相同的协议、域名和端口
2.访问限制
无法使用网页的DOM对象
window对象改写成self
不能执行alert()和confirm()方法
支持chrome的console和debugger断点
3.使用异步
使用XMLHttpRequst发出AJAX请求
使用setInterval()和setTimeout()
使用websocker进行持续链接
使用importScripts()加载脚本文件
应用场景:
1.使用专用线程进行数学运算
处理ajax返回的大批量数据,读取用户上传文件,
计算MD5,更改canvas的位图的过滤,分析视频和声频文件等。
2.高频用户交互
3.数据的预取
SetTimeOut伪线程
浏览器的内核是多线程的,一般至少实现三个常驻线程:
JavaScript引擎线程、GUI引擎线程、浏览器事件触发线程
* JavaScript引擎是基于事件驱动单线程
* GUI引擎线程浏览器界面,与JS引擎是互斥的,
当JS引擎执行时GUI线程会被挂起,GUI更新会保存在一个队列中等JS引擎空闲时被执行
* 事件触发线程,当事件触发时该线程将事件加到处理队列的队尾,等待JS引擎来处理
这些事件来源:
1.来自JS引擎执行的代码如SetTimeOut
2.浏览器内核的其他线程如鼠标点击、AJAX异步请求
SetTimeOut模拟一个多线程:
var thread = function () {
var nowTime = 0, //线程已经执行了多久
maxTime = 15;//线程最多执行多久
var threadArr = [];//数组模拟线程队列
this.addThread = function (fn) {
threadArr.push(fn)
}
this.start=function () {
doingThread();
}
var doingThread = function () {
if (threadArr.length > 0) {
if (nowTime < maxTime) {
let now = new Date().getTime();
var method = threadArr[0];
method();
threadArr.splice(0, 1);
let nowNew = (new Date().getTime() - now);
nowTime += nowNew;
doingThread();
} else {//每执行完线程后睡1ms
nowTime=0;
setTimeout(doingThread, 1);
}
}else {//先睡着等待线程队列
setTimeout(doingThread,100)
}
}
}
var fn = function (num) {
console.log(num)
}
var thread = new thread();
thread.start()
for (let i = 0; i < 1000000; i++) {
thread.addThread(function () {
fn(i)
})
}