javaScript中的任务队列和事件循环

单线程的javaScript
JavaScript从一诞生就是单线程的,未来也不会改变。虽然HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是新标准并没有改变JavaScript单线程的本质。

同步和异步
JavaScript中的任务可以分为两类:

  • 同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务。
  • 异步任务:不进入主线程、而进入"任务队列"(详情看下文)的任务,只有"任务队列"通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。

一个异步过程包括两个要素:注册函数和回调函数,其中注册函数用来发起异步过程,回调函数用来处理结果。

setTimeout(fn, time);

上面代码中,setTimeout就是注册函数,fn是回调函数。

一般而言,异步任务有以下三种类型:

  • 普通事件,如click
  • 资源加载,如load
  • 定时器,包括setIntervalsetTimeout等。

任务队列
JavaScript 运行时,除了一个正在运行的主线程,引擎还提供一个“任务队列”,里面是各种需要当前程序处理的异步任务。

"任务队列"是一个先进先出的数据结构,排在前面的事件,优先被主线程读取。主线程的读取过程基本上是自动的,只要执行栈一清空,“任务队列"上第一位的事件就自动进入主线程。但是,由于存在"定时器”,主线程首先要检查一下执行时间,某些事件只有到了规定的时间,才能返回主线程。

事件循环
下图中,主线程运行的时候,产生堆和栈,栈中的代码调用各种外部API,异步操作执行完成后,就在任务队列中排队。只要栈中的代码执行完毕,主线程就会去读取任务队列,依次执行那些异步任务所对应的回调函数。
在这里插入图片描述

详细步骤如下:

  • 所有同步任务都在主线程上执行,形成一个执行栈。
  • 主线程之外,还存在一个"任务队列"。只要异步操作执行完成,就到任务队列中排队。
  • 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
  • 主线程不断重复上面的第三步。

从代码执行顺序的角度来看,程序最开始是按代码顺序执行代码的,遇到同步任务,立刻执行;遇到异步任务,则只是调用异步函数发起异步请求。此时,异步任务开始执行异步操作,执行完成后到任务队列中排队。程序按照代码顺序执行完毕后,查询任务队列中是否有等待的异步任务。如果有,则按照次序从任务队列中取出放到执行栈中执行。执行完毕后,再从任务队列中获取异步任务,再执行,不断重复。
由于主线程不断的重复获得、执行异步任务;又由于“任务队列”是一个事件的队列,主线程读取“任务队列”就是读取里面有哪些事件,所以,这种机制被称为事件循环。

写在最后
本文参考文章如下:
JavaScript 运行机制详解:再谈Event Loop
深入理解javascript中的事件循环event-loop

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值