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知识库 -> 浏览器的事件循环机制进阶理解 -> 正文阅读

[JavaScript知识库]浏览器的事件循环机制进阶理解

浏览器的事件循环机制

由来: js是单线程(一次只能进行一下操作)的语言,主要是用于页面和用户之间的交互,因为如果是多线程在渲染的时候是会出现问题的,比如同时对一个dom进行输入和删除的操作,此时就会产生冲突,但是单线程没有多线程处理方法的话,也会有问题,比如ajax请求数据/定时器/事件绑定等,此时一直在等待服务器返回数据界面,出现阻塞,用户的体验感也会不好,效率也会很低,因此就产生了一些单线程中的异步操作。

异步操作
  • 主要包括定时器;事件绑定;ajax请求以及回调函数(不是很严谨的异步)

  • es6提供了 promise 和 Generator(生成器) 以及 es7 的 async/await 解决异步的方法

    • 由来: 防止回调地狱的形成(回调地狱:在js中我们经常会大量使用异步回调,将一个函数作为参数传递给另个函数并且有许多 })结尾的符号,使得代码看起来很混乱)

    • Promise有三种状态:pending/reslove/reject 。pending 就是未决,resolve 可以理解为成功,reject 可以理解为拒绝。

      • Promise 常用的三种方法 then 表示异步成功执行后的数据状态变为 reslove ;catch 表示异步失败后执行的数据状态变为 reject; all表示把多个没有关系的 Promise 封装成一个Promise 对象使用 then 返回一个数组数据。
    • Generator(生成器)是一种有效利用内存的机制,一边循环一边计算生成数值的机制。通过配合Promise 可以更加优雅的写异步代码。

      • 构建一个生成器函数

        function *f() {      
        	let x = yield f1();      
        	console.log("ni hao")  
        }
        

        构建生成器非常简单只需要在函数方法名前面加一个 * 这个函数就是一个生成器函数,可能有人注意到函数体中有一个 yield 关键字(学过 python 应该知道),简单点说 yield 类似 return 也是返回值的,区别在于当程序 执行到 yield 后会返回 yield 后面的表达式,并且程序暂停在这里保存当前值状态,程序只是暂停在这里并没有中止。

      • 获取生成器的值

        var it = f();    
        it.next().value.then(data=>{   
        	console.log(data) ;
        })  
        console.log(123) ; 
        it.next() ; 
        console.log(it.next());
        

        使用 next() 方法可以获取到yield第一次暂停的值返回的是 { value: 值 done: true } value 表示 yield 返回的值,done 表示是否迭代完毕。当然也可以使用 netx(10) 来给 yield 设置下次执行的值。

    • es7 的 async/await (异步等待)

      • 封装异步请求

        function f() {
            return new Promise((resolve, reject) => {
                setTimeout(()=>{
                    resolve("hello word")
                },1000)
            })
        }
        
      • 使用异步函数

        // 函数前面加async 表示该函数是一个异步函数 await 表示等待一个异步值的到来
        async function a(){
           var data = await f();
           return data;
        }
        
      • 获取值

        // 异步函数返回的是一个Promise对象,return返回的值通过使用then来进行获取
        var a = a()
         a.then(data=>{
             console.log(data)
         })
        

        貌似类似于生成器,只是把 * 换成async ,yield缓存await ?

        答:确实一样,但是生成器返回的是一个迭代器,而异步函数返回的是一个 Promise ,异步函数是可以以更加方便的同Promise结合使用来书写同步代码风格的异步执行。

事件(同步任务、宏任务和微任务)
  • 同步任务(MainTask):JavaScript按照正常顺序执行的代码。

    例如:函数调用,数值运算等等,特点就是执行后立即可以得到结果。

  • 宏任务(MacroTask):setTimeout、setInterval、I/O、UI渲染。

  • 微任务(MicroTask):Promise、Object.obsever、MutationObsever用户交互事件( User Interaction Event):点击事件 onclick 、键盘事件 onkeydown 、鼠标事件 onmouseover 等等

执行的顺序

具体流程:

  • 执行完主逻辑中的同步任务
  • 取出微任务队列(MicroTask Queue)中的任务执行,直到队列被完全清空然后取出宏任务队列(MacroTask Queue)中的一个任务执行。
  • 执行完了一个宏任务后取出微任务队列(MicroTask Queue)中的任务执行,直到队列被完全清空,重复 这个和 上一个,直到宏任务队列(MacroTask Queue)被清空。

举例
// 输出结果: 1 5 11 6 2 3 4 7 8 10 9
// 同步任务
console.log('1');
// 宏任务
setTimeout(function() {
    console.log('2');
    // 微任务
    new Promise(function(resolve) {
        console.log('3');
        resolve();
    }).then(function() {
        console.log('4')
    })
},0)
// 微任务
new Promise(function(resolve) {
    console.log('5');
    resolve();
}).then(function() {
    console.log('6')
})
// 宏任务
setTimeout(function() {
    console.log('7');
    new Promise(function(resolve) {
        console.log('8');
        resolve();
    }).then(function() {
        console.log('9')
    })
    console.log('10')
},0)
// 同步任务
console.log('11')
// 输出结果: 4 1 3 6 8 2 7 5(注意这里的3在2前面是因为先执行主线程任务(全局任务)后再执行微任务)
// 异步函数:被调用才会执行
async function async1() {
    console.log('1');
    await async2();
    console.log('2');
}
// 异步函数:被调用才会执行
async function async2() {
    console.log('3');
}
// 同步任务
console.log('4');
// 宏任务
setTimeout(function() {
    console.log('5');
}, 0)
// 同步任务
async1();
// 微任务
new Promise(function(resolve) {
    console.log('6');
    resolve();
}).then(function() {
    console.log('7');
});
// 同步任务
console.log('8');
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-19 07:54:08  更:2021-09-19 07:55:40 
 
开发: 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年11日历 -2024/11/23 18:41:45-

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