javascript的单线程
1.什么是javascript的单线程
javascript是单线程的语言,所以在一个进程上,只能运行一个县城,不能多个线程同时运行。
也就是说javascript不允许多个线程共享内存空间。
如果多个线程想同时运行,则必须采用排队的方式。即只有当前一个线程执行完毕,后一个线程才开始执行。
javascript的线程包括函数调用,I/O设备(ajax请求),定时器,用户操作事件(click,keyup等)
2.堆,栈,队列
堆(HEAP):存放对象。
javascript所有皆为对象,如函数是“可调用对象”,在函数被调用之前,javascript引擎会对函数进行编译,完成编译后,函数会被放入堆中,分配内存空间,等待执行或调用。
栈:执行栈。
如调用函数,响应用户操作事件。
当调用函数时,javascript引擎会创建一个执行栈,包含了被调用函数的参数和局部变量。
当被调用函数中又调用了其他函数时,如下所示:
function A(){ B(); }
此时,会把B函数推入执行栈,同时包含B函数的参数和局部变量。当B函数执行完毕后,B函数出栈,继承执行A函数,A函数执行完毕,出栈,整个执行栈就空了。然后主线程会读取任务队列中的其他任务。
队列:待执行任务队列
单线程意味着,所有任务都要排队,前一个任务执行完毕,才会执行后一个任务。
任务可以分为两种,同步任务和异步任务。
同步任务是指主线程上排队执行的任务,只有前一个任务执行完毕,后一个任务才会执行。
异步任务是指不进入主线程,而进入任务队列的任务(如回调函数,定时器,事件响应等),只有当主线程上的所有同步任务执行完毕后,主线程才会读取任务队列,开始执行异步任务。
3.定时器
定时器是异步任务,主线程会在所有同步任务执行完毕后,计算定时器的执行时间,再将事件推入执行栈。由此可知,定时器并不是完全准时执行的。
还需要注意的是,定时器在异步任务队列中是按时间长短排列的,时间越短,越早执行。
如以下代码所示:
function foo() { setTimeout(function() { console.log(1); }, 2000) console.log(2); } function bar() { setTimeout(function() { console.log(3); }, 1000); console.log(4); } function baz() { setTimeout(function() { console.log(5); }, 0) console.log(6); } foo(); bar(); baz(); //结果: 2, 4, 6, 5, 3, 1;