Event-Loop 详解

JavaScript是单线程

JavaScript是单线程的,也就是说同一时间只能做一件事。 这和它运行在浏览器有关,作为脚本语言,JavaScript只要用户操作DOM以及用户操作。 这决定了它只能是单线程,否则会带来很多复杂的同步问题。

HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程。
但是子线程完全受主线程控制,且不得操作DOM。
所以,这个新标准并没有改变JavaScript单线程的本质。
复制代码

任务队列

单线程意味着所有的任务都要排队,前一个任务结束了才会执行后一个任务。如果有些任务耗时过长,那么就不得不一直等待下去。
在JavaScript中,耗时较长的操作主要是用户操作、网络请求、IO设备。往往这个时候CUP是处于闲置的,造成资源浪费。JavaScript设计者意识到网络请求和IO设备等耗时操作可以暂时不管他,先执行后面的任务,等耗时的操作有了结果回调再去之后再去执行相应操作。这样大大的提高了资源的利用和代码运行速度。
因此任务分为同步任务和异步任务。简单来说,同步任务是在主线程上的任务,该任务只有在前面任务执行完毕才可以执行。异步任务则是进入任务队列(task queue),当得知改任务可以执行时才会进入主线程执行。

同步异步执行顺序如下:
(1)所有同步任务都在主线程上执行,形成一个执行栈

(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

(4)主线程不断重复上面的第三步。
复制代码

事件和回调函数

任务队列就是事件队列。每当IO设备完成一项任务,就在任务队列添加一个事件。意味着相关的异步操作可以进入执行栈。
任务队列中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入"任务队列",等待主线程读取。
回调函数就是被主线程挂起的代码,异步任务必须制定回调函数,当主线程开始执行异步操作,就是执行相应的回调函数。
任务队列是先进先出的数据结构。同时主线程读取任务队列的规则是,主线程执行栈空是就去读取任务队列。

Event Loop

下图转引自Philip Roberts的演讲的PPT
有兴趣的同学看这里《Help, I'm stuck in an event-loop》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值