js运行机制(事件循环 Event Loop)

在了解javascript运行机制前 我们需要了解一下以下几点:

  • javascript是多线程还是单线程?

  • 一个简单的测试

  • javascript中的 同步任务与异步任务

  • javascript中的 执行栈

  • javascript中的回调函数和事件

  • Javascript中的任务队列

  • javascript中的Event Loop

javascript是多线程还是单线程?

JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。

一个简单的测试,思考一下 以下代码 的运行结果

function syncAndAsync() {
    console.log("1") //步骤1
    setTimeout(() => {//步骤3
      console.log("2")
    }, 1000);
    console.log("3")//步骤2
  }

运行结果:1,3,2
为什么 是这样的结果呢?

如果把步骤2的时间改为0秒 结果会如何呢?

请读完js的运行机制后 ,答案就很明了了。

javascript中的同步任务与异步任务

因为javascript是单线程的 ,所以 javascript 把运行的任务,设计了两种 同步任务和异步任务

同步任务指的是:在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;

异步任务指的是:不进入主线程、被主线程挂起的任务,只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。当主线程 的所有同步任务执行完后,查看该任务队列 的事件,对应的任务 结束等待状态,进入执行栈,开始执行。

javascript中的 执行栈

所有同步任务都是在主线程上执行的,这些同步任务在主线程上的执行,这就是执行栈。

javascript中的回调函数

回调函数,就是那些会被主线程挂起来的任务。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。

Javascript中的任务队列

"任务队列"是一个事件的队列(也可以理解成消息的队列),队列中对应的任务有了结果(比如读取文件(io操作),请求远程数据等等),就在"任务队列"中添加一个事件,表示相关的异步任务可以进入"执行栈"了。主线程读取"任务队列",就是读取里面有那些事件。

"任务队列"中的事件,除了IO设备的事件以外,还包括一些用户产生的事件(比如鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入"任务队列",等待主线程读取。

javascript中的Event Loop

主线程先执行同步任务,也就是执行栈中的 任务,当执行完所有的执行栈中的任务后 ,从"任务队列"中读取事件,然后执行对应可执行状态的异步任务(回调)。这个过程是不断循环的,所以整个的这种运行机制又称为Event Loop(事件循环)。

异步执行的运行机制步骤如下:

1,所有同步任务都在主线程上执行,形成一个执行栈(execution context stack),排队执行。
2,主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
3,一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
4,主线程不断重复上面的第三步。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章