React-7 异步

78 阅读3分钟

同步 异步

你去商城买东西,你看上了一款手机,能和店家说你一个这款手机,他就去仓库拿货,你得在店里等着,不能离开,这叫做同步。现在你买手机赶时髦直接去京东下单,下单完成后你就可用做其他时间(追剧、打王者、lol)等货到了去签收就ok了.这就叫异步。

上文来源

image.png

图片来源

异步场景

  • 定时任务:setTimeout, setInterval
  • 网络请求:前端向后台请求API数据,图片加载
  • 事件监听:addEventListener

为什么js是单线程?

js作为主要运行在浏览器的脚本语言,js主要用途之一是操作DOM。

例子,如果js同时有两个线程,同时对同一个dom进行操作,这时浏览器应该听哪个线程的,如何判断优先级

为了避免这种问题,js必须是一门单线程语言,并且在未来这个特点也不会改变。

上文来源

事件循环 Event loop

同步代码不受事件循环影响,不会进入callback Queue

执行栈 与 任务队列

  • 主线程 规定现在执行执行栈中的哪个事件。

即主线程会不停的从执行栈中读取事件,会执行完所有栈中的同步代码

当遇到一个异步事件后,并不会一直等待异步事件返回结果,而是会将这个事件挂在与执行栈不同的队列中,我们称之为任务队列(Task Queue)

当主线程将执行栈中所有的代码执行完之后,主线程将会去查看任务队列是否有任务。如果有,那么主线程会依次执行那些任务队列中的回调函数。

  • 总结:js 异步执行的运行机制

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

  • 执行栈 事件发生时会进入执行栈中,等待主线程读取,遵循先进先出原则。

  • 任务列表

    • 宏任务 :setTimeout、setInterval
    • 微任务 :Promise
  • 事件循环(Event Loop),每一次循环称为 tick, 每一次tick的任务如下:

    • 执行栈选择最先进入队列的宏任务,如果有则执行
    • 检查是否存在 Microtask,如果存在则不停的执行,直至清空 microtask 队列
    • 更新render(每一次事件循环,浏览器都可能会去更新渲染)
    • 重复以上步骤

宏任务 > 所有微任务 > 宏任务

上文来源 image.png DEMO来源于文章

补充内容:Promise

状态变化

new Promise() 返回两种结果

  • 初始
    • status: "pending"
    • result: undefined
  • 初始-resolve("done")→ 成功
    • status: "fullfilled"
    • result: "done"
  • 初始-resolve("error")→ 失败
    • status: "rejected"
    • result: "error"
new Promise(()=>{...})
    .then((response)=>{ // 成功 call API
      console.log(response);
    })
    .catch(err => console.log(err)); //失败 call API

Axios

  • 概念

一个基于promise的第三方HTTP库,内容使用的是XMLHttpRequest 支持nodejs和浏览器环境,兼容性好

  • 使用
import axios from "axios"
axios.get(url).then((response)=>{
  console.log(response.data); //直接拿到data
})