js线程模型


客户端javascript是单线程,浏览器无法同时运行两个事件处理程序

设计为单线程的理论是,客户端的javascript函数必须不能运行太长时间,否则会导致web浏览器无法对用户输入做出响应。这也是为什么Ajax的API都是异步的,以及为什么客户端Javascript不能使用一个简单的异步load()或者require()函数来加载javascript库

如果应用程序不得不执行太多的计算而导致明显的延迟,应该允许文档在执行这个计算之前完全载入,并且确保告诉用户正在进行计算并且浏览器没有挂起。如果可能应该将任务分散为离散的子任务,可以使用setTimeout()和setInterval()方法在后台运行子任务,同时更新一个进度指示器向用户显示反馈

Web worker简介


HTML5定义了一种作为后台线程的WebWorker。 web worker是一个用来执行计算密集任务而不冻结用户界面的后台线程。

Web worker无法访问window对象和document对象,和主线程之间的通信也只能通过异步消息传递机制来实现。

Web worker 本身不是轻量级的线程,因而常见一些worker去处理次要的操作是不划算的

浏览器支持情况:

包含两部分:

  1. Worker对象:暴露给创建该线程的线程

  2.  WorkerGlobalScope:用来表示新创建的worker的全局对象

Web Worker基本使用


创建新的Worker:

var worker= new Worker("/assets/demo.js");

传递参数:

worker.postMessage("file.text");

接收消息:

worker.onmessage = function(e){
var message = e.data;
......
}

Worker当然也支持addEventListener()方法和removeEventListener()方法,如果需要管理多个事件时可以使用哒

异常处理:

worker.onerror = function(e){
console.log("Error at " + e.filename + ":" +e.lineno + e.message );
}

结束Worker

worker.terminate();

载入类和工具函数:

importScripts("utils/base64.js","utils/Map.js"....);

注意:importScripts是同步的方法,一旦importScripts方法返回就可以开始使用载入的脚本,不需要回调函数

Worker作用域


当创建一个新的Worker时该代码会运行在一个全新的Javascript运行环境中(WorkerGlobalScope),完全与创建Worker的脚本隔离

WorkerGlobalScope是Worker的全局对象,因而它包含所有核心Javascript全局对象拥有的属性如JSON等,window的一些属性如self等,也拥有类似XMLHttpRequest()函数

下面简单概括下worker所支持的属性和方法:

self

setTimeout、clearTimeout、setInterval、clearInterval

location

navigator

onerror

XMLHttpRequest

addEventListener、removeEventListener

简单例子


eg1:

html:

<div id="div">
<p>
计数:
<output id="result"></output>
</p>
<button onclick="startWorker()">开始 Worker</button>
<button onclick="stopWorker()">停止 Worker</button> <br />
<br />
<button onclick="mainWork()"> click me </button>
<br />
<br />
</div>

js脚本:

    var w;

        function startWorker() {
if (typeof (Worker) !== "undefined") {
if (typeof (w) == "undefined") {
w = new Worker("demo.js");
}
w.onmessage = function(event) {
document.getElementById("result").innerHTML = event.data;
};
} else {
document.getElementById("result").innerHTML = "Sorry, your browser does not support Web Workers...";
}
} function stopWorker() {
w.terminate();
} function addE(){
var p = document.createElement('p');
p.innerHTML="WISH YOU HAPPY~";
div.appendChild(p);
}

demo.js:

/**
* Web Worker Demo----count
*
*/
var i=0; function timedCount()
{
i=i+1;
postMessage(i);
setTimeout("timedCount()",500);
} timedCount();

结果:

点击开始Worker后,计数在后台进行,可以点击click me,相互不影响


eg2:

如上面所说,我们应该尽量使用WebWorker处理计算量大的,主要的工作,否则因为WebWorker本身不是轻量级的线程,因而有点得不偿失

本例使用WebWoker处理图片,将图片模糊,顺便学习下canvas,如下:

html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
img {
width: 400px;
height: 300px;
}
</style>
</head>
<body>
<img src="../images/demo.png" onclick="smear(this)"/>
<img src="../images/1.png" onclick="smear(this)"/>
<img src="../images/2.png" onclick="smear(this)"/>
<script>
function smear(img){
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height; var context = canvas.getContext("2d");
context.drawImage(img,0,0);
var pixels = context.getImageData(0,0,img.width,img.height); var worker = new Worker("SmearWorker.js");
worker.postMessage(pixels); worker.onmessage = function(e){
var smeared_pixels = e.data;
context.putImageData(smeared_pixels,0,0);
img.src = canvas.toDataURL();
worker.terminate();
canvas.width = canvas.height = 0;
}
}
</script> </body>
</html>

SmearWorker.js:

/**
* SmearWorker---smear the picture
*/ function smear(pixels){
var data = pixels.data,
width = pixels.width,
height = pixels.height; var n = 10,
m = n-1,
i,
col; for(var row=0; row<height; row++){
i = row*width*4 + 4;
for(col =1;col<width; col++,i+=4){
data[i] = (data[i] +data[i-4]*m/n);
data[i+1] = (data[i+1] +data[i-3]*m/n);
data[i+2] = (data[i+2] +data[i-2]*m/n);
data[i+3] = (data[i+3] +data[i-1]*m/n); }
}
return pixels;
} onmessage = function(e){
postMessage(smear(e.data));
};

结果如下:

图片点击前:

点击第一张和第三张图片:

其他


我们在js中使用XMLHttpRequest时经常会设置为异步方式,因而在主浏览器线程张使用同步很不好,我们可以在worker中使用同步的XMLHttpRequest

JS线程模型&Web Worker的更多相关文章

  1. js 性能优化 - web worker

    当在 HTML 页面中执行脚本时,页面的状态是不可响应的,直到脚本已完成. web worker 是运行在后台的 JavaScript,独立于其他脚本,不会影响页面的性能. 您可以继续做任何愿意做的事 ...

  2. 使用Actor模型管理Web Worker多线程

    前端固有的编程思维是单线程,比如JavaScript语言的单线程.浏览器JS线程与UI线程互斥等等,Web Woker是HTML5新增的能力,为前端带来多线程能力.这篇文章简单记录一下搜狗地图WebG ...

  3. 深入HTML5 Web Worker应用实践:多线程编程

    HTML5 中工作线程(Web Worker)简介 至 2008 年 W3C 制定出第一个 HTML5 草案开始,HTML5 承载了越来越多崭新的特性和功能.它不但强化了 Web 系统或网页的表现性能 ...

  4. 深入 HTML5 Web Worker 应用实践:多线程编程

    深入 HTML5 Web Worker 应用实践:多线程编程 HTML5 中工作线程(Web Worker)简介 至 2008 年 W3C 制定出第一个 HTML5 草案开始,HTML5 承载了越来越 ...

  5. 理解微信小程序的双线程模型

    有过微信小程序开发经验的朋友应该都知道"双线程模型"这个概念,本文简单梳理一下双线程模型的一些科普知识,学识浅薄,若有错误欢迎指正. 我以前就职于「小程序·云开发」团队,在对外的一 ...

  6. Web Worker javascript多线程编程(一)

    什么是Web Worker? web worker 是运行在后台的 JavaScript,不占用浏览器自身线程,独立于其他脚本,可以提高应用的总体性能,并且提升用户体验. 一般来说Javascript ...

  7. Web Worker javascript多线程编程(二)

    Web Worker javascript多线程编程(一)中提到有两种Web Worker:专用线程dedicated web worker,以及共享线程shared web worker.不过主要讲 ...

  8. 关于Web Worker你必须知道的7件事

    介绍 通过使用Web Worker, 我们可以在浏览器后台运行Javascript, 而不占用浏览器自身线程.Web Worker可以提高应用的总体性能,并且提升用户体验.如果你想在自己的Web应用中 ...

  9. html5之web worker

    Web Worker   在本文中 与 Web Worker 进行双向通信 WindowTimers 在 IE10 Platform Preview 4 中对 Web Worker 的更新 API 参 ...

随机推荐

  1. Android上使用OpenGLES2.0显示YUV数据

    在Android上用OpenGLES来显示YUV图像,之所以这样做,是因为: 1.Android本身也不能直接显示YUV图像,YUV转成RGB还是必要的: 2.YUV手动转RGB会占用大量的CPU资源 ...

  2. Word查找和替换通配符(完全版)

    Word查找栏代码·通配符一览表 序号 清除使用通配符复选框 勾选使用通配符复选框 特殊字符 代码 特殊字符 代码or通配符 1 任意单个字符 ^? 任意单个字符 ? 2 任意数字 ^# 任意数字(单 ...

  3. JS遍历对象或者数组

    一.纯js实现 <script> var obj = {"player_id":"GS001","event_id":" ...

  4. 用ASP.net判断上传文件类型的三种方法

    一. 安全性比较低,把文本文件1.txt改成1.jpg照样可以上传,但其实现方法容易理解,实现也简单,所以网上很多还是采取这种方法. Boolean fileOk = false;           ...

  5. protocol buffer使用简介

    之前在工作中用到了protocol buffer(此处简称PB)(主要对数据进行序列化与反序列化,方便网络传输中的编解码),之后发现这是一个好东西,在此稍微记录下该工具如何使用,方便以后查阅 官网地址 ...

  6. 创建DBLink语句

    --linkName DBLink名 --username 用户名 --password 密码 --tns TNS配置字符串 create database link &linkName co ...

  7. [转] iOS SDK:iOS调试技巧

    原文:  http://www.cocoachina.com/ios/20130517/6225.html 为什么你的数组包含3个项目而不是5个?为什么你的游戏运行缓慢?这些都跟调试有关,调试是开发过 ...

  8. Qt零基础教程(四)QWidget详解(3):QWidget的几何结构

    Qt零基础教程(四)  QWidget详解(3):QWidget的几何结构 这篇文章里面分析了QWidget中常用的几种几何结构 下图是Qt提供的分析QWidget几何结构的一幅图,在帮助的 Wind ...

  9. MVC3中 ViewBag、ViewData和TempData的使用和区别(转发:汴蓝)

    MVC3中 ViewBag.ViewData和TempData的使用和区别   在MVC3开始,视图数据可以通过ViewBag属性访问,在MVC2中则是使用ViewData.MVC3中保留了ViewD ...

  10. Win7 64位 php-5.5.13+Apache 2.4.9+mysql-5.6.19 配置

    一 :准备阶段 1:php php-5.5.13下载链接:http://windows.php.net/downloads/releases/php-5.5.13-Win32-VC11-x64.zip ...