理解同步,异步和 事件循环, 宏,微任务执行顺序

一. 单线程

单线程,是指在JS引擎中负责解释和执行JavaScript代码的线程只有一个 ,不妨叫它主线程

但是实际上还存在其他的线程。例如:处理AJAX请求的线程、处理DOM事件的线程、定时器线程、读写文件的线程(例如在Node.js中)等等。这些线程可能存在于JS引擎之内,也可能存在于JS引擎之外,在此我们不做区分。不妨叫它们工作线程。

js是单线程的,一个任务完成后才能执行另一个

二. 同步和异步

假设存在一个函数A:

A(args...);
同步:如果在函数A返回的时候,调用者就能够得到预期结果(即拿到了预期的返回值或者看到了预期的效果),那么这个函数就是同步的。

例如:

Math.sqrt(2);
console.log('Hi');
  • 第一个函数返回时,就拿到了预期的返回值:2的平方根。

  • 第二个函数返回时,就看到了预期的效果:在控制台打印了一个字符串。

所以这两个函数都是同步的。

异步:如果在函数A返回的时候,调用者还不能够得到预期结果,而是需要在将来通过一定的手段得到,那么这个函数就是异步的。

例如:

fs.readFile('foo.txt', 'utf8', function(err, data) {
    console.log(data);
});

在上面的代码中,我们希望通过fs.readFile函数读取文件foo.txt中的内容,并打印出来。
但是在fs.readFile函数返回时,我们期望的结果并不会发生,而是要等到文件全部读取完成之后。如果文件很大的话可能要很长时间。
下面以AJAX请求为例,来看一下同步和异步的区别:

异步AJAX:

  • 主线程:“你好,AJAX线程。请你帮我发个HTTP请求吧,我把请求地址和参数都给你了。”

  • AJAX线程:“好的,主线程。我马上去发,但可能要花点儿时间呢,你可以先去忙别的。”

  • 主线程::“谢谢,你拿到响应后告诉我一声啊。”

(接着,主线程做其他事情去了。一顿饭的时间后,它收到了响应到达的通知。)

从上文可以看出,异步函数实际上很快就调用完成了。但是后面还有工作线程执行异步任务、通知主线程、主线程调用回调函数等很多步骤。我们把整个过程叫做异步过程。异步函数的调用在整个异步过程中,只是一小部分。

总结一下,一个异步过程通常是这样的:

主线程发起一个异步请求,相应的工作线程接收请求并告知主线程已收到(异步函数返回);
主线程可以继续执行后面的代码,同时工作线程执行异步任务;
工作线程完成工作后,通知主线程;主线程收到通知后,执行一定的动作(调用回调函数)。

异步函数通常具有以下的形式:

A(args..., callbackFn)
它可以叫做异步过程的发起函数,或者叫做异步任务注册函数。args是这个函数需要的参数。callbackFn也是这个函数的参数,但是它比较特殊所以单独列出来。

所以,从主线程的角度看,一个异步过程包括下面两个要素:

  • 发起函数(或叫注册函数)A

  • 回调函数callbackFn

它们都是在主线程上调用的,其中注册函数用来发起异步过程,回调函数用来处理结果。

三. 消息队列和事件循环

上文讲到,异步过程中,工作线程在异步操作完成后需要通知主线程。那么这个通知机制是怎样实现的呢?答案是利用消息队列和事件循环。
用一句话概括:

工作线程将消息放到消息队列,主线程通过事件循环过程去取消息。

  • 消息队列:消息队列是一个先进先出的队列,它里面存放着各种消息。

  • 事件循环:事件循环是指主线程重复从消息队列中取消息、执行的过程。
    例:

setTimeout(() => {
            console.log('hello');
        }, 1000);

1秒后,console.log('hello');被放在任务队列(消息队列)里
当主线程执行完任务后会从消息队列中拿任务在执行,
主线程只有在将当前的消息执行完成后,才会去取下一个消息。这种机制就叫做事件循环机制,取一个消息并执行的过程叫做一次循环。

实际上,主线程只会做一件事情,就是从消息队列里面取消息、执行消息,再取消息、再执行。
image

四.宏任务,微任务以及执行顺序

异步任务:

  • 计时器
  • ajax
  • 读取文件
    同步程序执行完成后在执行异步任务

宏任务:

  • 计时器 ajax 读取文件

微任务:

  • promise.then()

执行顺序:

  • 1.同步任务
  • 2.process.nextTick
  • 3.微任务
  • 4.宏任务
  • 5.setImmeduate
posted @ 2022-04-07 15:47  Kira的学习笔记  阅读(118)  评论(0)    收藏  举报