文档章节

javascript中的线程之我见

mj4738
 mj4738
发布于 2013/02/11 08:56
字数 987
阅读 326
收藏 8
今天与一个同事争论javascripe中间的线程机制,他争论说javascript是有线程的,理由即使javascript中间的事件回调就是线程的实现,个人认为在javascript中是没有线程机制的

理由如下:

引自《精通javascript》 john resig著:

<script>
  while(!window.loaded);
  //some operation 
   window.alert();
</script>

    这段代码的意图就是想阻塞当前js线程, 直到页面完全加载完毕才执行后续操作。但是得到的效果却是浏览器暂停或者假死,可见在js中是不能用循环来暂停等待的。要实现这个效果必须采用回调:

wndow.onload=funcrion(){
//some operation
}


    然而回调不是js语言中支持多线程的依据。我们知道在windows中的回调消息机制是这样的:
windows把单击事件和一个处理函数关联起来,当我们点击了某个按钮的时候,系统会调用这个单击事件的处理函数。实际上,windows内部会维护一张事件处理表,这个表中单击事件对应一个处理函数的函数指针。当点击事件发生时,windows会调用这个函数指针所指向的函数。

    那什么是线程? 我想我们应该从支持多线程的操作系统说起。多线程就是让多个计算过程交替执行并且这个交替的时间片很短,短到我们无法感知。这就是为什么单处理器也可以并发执行线程。操作系统会维护多个状态的线程队列,并决定采取何种调度算法来切换线程之间的执行.  

    js中没有线程的概念,或者说所有的操作到放在同一个线程(即单线程)中。那么应该如何来模拟这个线程机制呢。既然js引擎没有为我们维护一个线程列表,那么我们自己来实现(这个线程列表和调度算法):

<script language="javascript">
    var thread_one_time=0;
    var thread_two_time=0;
    function thread_one(){
        thread_one_time++;    
        alert( thread_one_time);
    }
     
    function thread_two(){
        thread_two_time++;
        alert( thread_two_time);
    }   
    setInterval(thread_one,100);
    setInterval(thread_two,100);
    
    for (var i =0; i< 10; i++){
       alert('主线程: '+i);
    }
</script>

在这里,我们就可以看见两个子程序交替执行了,其实,如果用线程的眼光看的话,这里是有三个线程的,一个是thread_one 一个是thread_two一个是main_thread(不过它先执行完)。这里的主线程可以看成操作系统中的进程(线程)管理器,由它来调度、切换和管理整个系统的线程。这里main采用的”调度算法“很朴实,就是100秒的时间片轮转,没有优先级,没有中断。

    下面给出一个完整的线程管理器例子:

thread.js: 

/**
 * 线程管理类
 * @param _task 任务函数
 * @param _delay 间隔时间(单位毫秒)
 * @param _times 执行次数(-1表示永远执行)
 * @author zxub 2006-06-12
 */
function Thread(_task,_delay,_times)
{
    this.runFlag=false;
    this.busyFlag=false;
    this.taskArgs=Array.prototype.slice.call(arguments,3);
    
    if (_times!=undefined)
    {
        this.times=_times;
    }
    else
    {
        this.times=1;
    }
    
    var _point=this;
    
    this.timerID=-1;
    
    this.start=function()
    {
        if (this.runFlag==false)
        {
            this.timerID=window.setInterval(_point.run,_delay);            
            this.runFlag=true;
        }
    }
    
    this.run=function()
    {
        if (_point.busyFlag){
		   return;
        }else if (_point.times==-1){
            _task(_point.taskArgs);
        }else if (_point.times>0){
            _task(_point.taskArgs);
            _point.times-=1;
            if (_point.times==0){
                window.clearInterval(this.timerID);
            }                                  
        }        
    }
    
    this.sleep=function()
    {
        this.busyFlag=true;
    }
    
    this.resume=function()
    {
        this.busyFlag=false;
    }
    
    this.abort=function()
    {        
        window.clearInterval(this.timerID);        
    }
}

thread.html:

<html>
<head>
<title>测试</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="thread.js"></script>    
<style type="text/css">
<!--
body,tr,td { font-size: 12px;}
-->
</style>
</head>
<body>
<script>
var func=function(_o)
{
    document.getElementById(_o).innerHTML=parseInt(document.getElementById(_o).innerHTML)+1;
}
var t1=new Thread(func,50,121,"t1");
var t2=new Thread(func,200,20,"t2");
</script>
<input type="button" value="start1" onclick='t1.start();'></input>
<input type="button" value="sleep1" onclick='t1.sleep();'></input>
<input type="button" value="resume1" onclick='t1.resume();'></input>
<input type="button" value="abort1" onclick='t1.abort();'></input>
<input type="button" value="start2" onclick='t2.start();'></input>
<input type="button" value="sleep2" onclick='t2.sleep();'></input>
<input type="button" value="resume2" onclick='t2.resume();'></input>
<input type="button" value="abort2" onclick='t2.abort();'></input>
<div id="t1">0</div> | <div id="t2">0</div>
<input type="button" value="t1.timerID" onclick='alert(t1.timerID);'></input>
<input type="button" value="t2.timerID" onclick='alert(t2.timerID);'></input>
</body>
</html>



本文转载自:http://blog.csdn.net/turkeyzhou/article/details/2784934

mj4738

mj4738

粉丝 296
博文 489
码字总数 119327
作品 0
崇明
高级程序员
私信 提问
JavaScript定时机制setTimeout与setInterval研究

容易欺骗别人感情的JavaScript定时器 本文转自:爱微网 JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都...

西西爱OS
2012/10/25
80
0
JavaScript可否多线程? 深入理解JavaScript定时机制

JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都深有同感, 例如 setTimeout( function(){ alert(’你好...

李长春
2012/11/09
98
0
Javascript是单线程的深入分析

面试的时候发现99%的童鞋不理解为什么JavaScript是单线程的却能让AJAX异步发送和回调请求,还有setTimeout也看起来像是多线程的?还有non-blocking IO, event loop等概念很不清楚。来深入分析...

stone_
2014/04/15
127
0
JavaScript可否多线程? 深入理解JavaScript定时机制

JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都深有同感, 例如 setTimeout( function(){ alert(’你好...

李长春
2012/11/09
87
0
使用 Web Workers 提高 web 应用程序可用性

简介: Web Workers,一个新的 JavaScript 编程模型,可以提高您 web 应用程序的交互性。有了它您就可以以一种多线程方法运行 JavaScript,而且可以在后台运行脚本而不依赖任何用户界面脚本。...

IBMdW
2011/11/03
544
0

没有更多内容

加载失败,请刷新页面

加载更多

实战项目-学成在线(一)

之前看的黑马程序员实战项目之一,打算以博客的形式写出来,也让自己重新温习一下。 1、项目背景 略(就是当前这东西很火,我们重点在开发,这些就略过) 2、功能模块 门户,学习中心,教学管...

lianbang_W
42分钟前
5
0
基于Vue的数字输入框组件开发

本文转载于:专业的前端网站➫基于Vue的数字输入框组件开发 1、概述 Vue组件开发的API:props、events和slots 2、组件代码 github地址:https://github.com/MengFangui/VueInputNumber 效果:...

前端老手
51分钟前
4
0
百度地图根据经纬度获取运动轨迹

<!DOCTYPE html><html><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="initial-scale=1.0, user-scalable=n......

泉天下
53分钟前
5
0
学习记录(day04-axios增删改查、v-for循环、页面加载成功处理函数)

[TOC] 1.1 基本语法:插值表达式 <template> <div> {{username}} <br/> {{1+2+3}} <br/> {{'你的名字是:' + username}} <br/> {{'abc'.split('')}} </div><......

庭前云落
今天
5
0
CentOS Linux 7上将ISO映像文件写成可启动U盘

如今,电脑基本上都支持U盘启动,所以,可以将ISO文件写到U盘上,用来启动并安装操作系统。 我想将一个CentOS Linux 7的ISO映像文件写到U盘上,在CentOS Linux 7操作系统上,执行如下命令: ...

大别阿郎
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部