IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 事件循环以及Async/Await -> 正文阅读

[JavaScript知识库]事件循环以及Async/Await

任务队列

  • 同步任务:立即执行的任务,同步任务一般会直接进入到主线程中执行;
  • 异步任务:异步执行的任务,比如ajax网络请求,setTimeout 定时函数,异步任务会通过任务队列的机制(先进先出的机制)来进行协调。

主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行。

在这里插入图片描述

上述过程的不断重复就是我们说的 Event Loop (事件循环)

宏任务和微任务

  • Macro Task (宏任务):script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)
    在ECMAScript中,macrotask可称为task
  • Micro Task(微任务):Promise、MutaionObserver、process.nextTick(Node.js 环境)
    在ECMAScript中,microtask称为jobs
    在node环境下,process.nextTick的优先级高于Promise。简单理解:在宏任务结束后会先执行微任务队列中的nextTickQueue部分,然后才会执行微任务中的Promise部分。

每个宏任务结束后, 都要清空所有的微任务

1.在此次 tick 中选择最先进入队列的任务( oldest task ),如果有则执行(一次)
2.检查是否存在 Microtasks ,如果存在则不停地执行,直至清空Microtask Queue
3.更新 render
4.主线程重复执行上述步骤

在这里插入图片描述

示例一

console.log('script start');

setTimeout(function() {
  console.log('setTimeout');
}, 0);

Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});

console.log('script end');
  1. 整体script作为第一个宏任务进入主线程,遇到console.log('script start');,输出script start
  2. 遇到setTimeout,其回调函数被分发到宏任务Event Queue 中
  3. 遇到Promise,其then函数被分到微任务Event Queue中,记为then1,然后又遇到then函数,将其分配到微任务Event Queue中,记为then2
  4. 遇到console.log('script end');,输出script end

现在宏任务队列和微任务队列如下:
在这里插入图片描述

  1. 执行微任务,首先执行then1,输出 promise1;
    然后执行 then2,输出 promise2 ,清空所有微任务
  2. 执行宏任务 setTimeout ,输出 setTimeout

至此,输出的顺序是:script start, script end, promise1, promise2, setTimeout

Async/Await

async

当我们在函数前使用async的时候,使得该函数返回的是一个Promise对象
async的函数会在这里帮我们隐式使用Promise.resolve(1)

async function test() {
    return 1   
}

等价于下面的代码

function test() {
   return new Promise(function(resolve, reject) {
       resolve(1)
   })
}

await

await表示等待,是右侧「表达式」的结果,这个表达式的计算结果可以是 Promise 对象的值或者一个函数的值(换句话说,就是没有特殊限定)。并且只能在带有async的内部使用

使用await时,会从右往左执行,当遇到await时,会阻塞函数内部处于它后面的代码,去执行该函数外部的同步代码,当外部同步代码执行完毕,再回到该函数内部执行剩余的代码,并且当await执行完毕之后,会先处理微任务队列的代码

示例二

async function async1() {
    console.log( 'async1 start' )
    await async2()
    console.log( 'async1 end' )
}
async function async2() {
    console.log( 'async2' )
}
console.log( 'script start' )
setTimeout( function () {
    console.log( 'setTimeout' )
}, 0 )
async1();
new Promise( function ( resolve ) {
    console.log( 'promise1' )
    resolve();
} ).then( function () {
    console.log( 'promise2' )
} )
console.log( 'script end' )

在这里插入图片描述

使用事件循环机制分析:

  1. 首先执行同步代码,console.log( 'script start' )
  2. 遇到setTimeout,会被推入宏任务队列
  3. 执行async1(), 它也是同步的,只是返回值是Promise,在内部首先执行console.log( 'async1 start' )
  4. 然后执行async2(), 然后会打印console.log( 'async2' )
  5. 从右到左会执行, 当遇到await的时候,阻塞后面的代码,去外部执行同步代码
  6. 进入 new Promise,打印console.log( 'promise1' )
  7. .then放入事件循环的微任务队列
  8. 继续执行,打印console.log( 'script end' )
  9. 外部同步代码执行完毕,接着回到async1()内部。
    由于async2()其实是返回一个Promise, await async2()相当于获取它的值,其实就相当于这段代码Promise.resolve(undefined).then((undefined) => {}),所以.then会被推入微任务队列, 所以现在微任务队列会有两个任务。
    接下来处理微任务队列,打印console.log( 'promise2' ),后面一个.then不会有任何打印,但是会执行
  10. 执行后面的代码, 打印console.log( 'async1 end' )
  11. 进入第二次事件循环,执行宏任务队列, 打印console.log( 'setTimeout' )
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-22 13:28:04  更:2021-08-22 13:28:17 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 5:17:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计