JS中的同步和异步

199 阅读3分钟

同步的理解:

同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;

同步就相当于是 当客户端发送请求给服务端,在等待服务端响应的请求时,客户端不做其他的事情。当服务端做完了才返回到客户端。这样的话客户端需要一直等待。用户使用起来会有不友好。

异步的理解:

异步是指进程不需要一直等下去,而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
异步就相当于当客户端发送给服务端请求时,在等待服务端响应的时候,客户端可以做其他的事情,这样节约了时间,提高了效率。

概况:同步是阻塞模式,异步是非阻塞模式

举个栗子

  • 比方说一个人边吃饭,边看手机,边说话,就是异步处理的方式。
  • 同步处理就不一样了,说话后在吃饭,吃完饭后在看手机,必须等待上一件事完了,才执行后面的事情。

在同步代码中,以下代码会导致程序卡死

死循环: 千万不要再JS中写死循环,否则会导致程序卡死

程序报错: 一旦程序发生报错,程序就会停止执行

throw new Error('xxx') 手动抛出错误

我们基于tyr/catch 进行异常捕获 这样不会影响后续代码的执行

在JS中也存在“异步编程”,依托于浏览器的多线程,再基于EventLoop事件循环机制,以下是JS中的异步代码

异步宏任务 macrotask

setTimeOut/setInterval(定时器)
事件绑定
Ajax/Fetch

异步微任务 microtask

  1. promise.then/catch/finally
  2. requestAnimationFrame(根据屏幕刷新率制作动画)
  3. async/await
  4. IntersectionObserver
  5. queueMicrotask 基于这个方法可以创建一个微任务

EventLoop事件循环机制

浏览器是多线程的,但是它只分配一个'JS引擎线程',所以JS是单线程的。而在JS中的大部分代码都是同步编程的。例如:循环...。我们一旦在程序中写了一个死循环就会一直占用JS引擎线程,导致下边的代码无法执行。

浏览器打开一个页面,除了开辟堆栈内存,还会默认创建两个队列

  • webAPI队列:监测异步任务是否可以执行
  • EventQueue队列:存储所有可执行的异步任务,在这个队列中排队等待执行

1.JS代码执行过程中,遇到异步任务,会把其放在webAPI中去监听:监听啥时候可以执行 此过程需要浏览器分配其他线程帮助我们进行监测才可以

2.如果webAPI监测的某个异步任务可以执行了,也不会立即拿到栈中去执行;而是先把其放在EventQueue中排队等着

3.当栈中所有"同步任务"都执行完,主线程空闲下来的时候,再去EventQueue中,把正在排队的异步任务拿出来执行

微任务优先级高于宏任务:如果排队的微任务,则先执行微任务,不论它是啥时候进来的!!

同类型的任务,优先执行队列开始的

特殊:异步任务也是拿到栈中,交给主线程执行.所以,如果执行中出现死循环,主线程一样会被占用,其他异步任务也无法再执行了