async 与 await 是否阻塞进程?

2022-12-30 0 230

1. async与await 的表述

async

新闻稿两个表达式是触发器的,回到两个 Promise 第一类。假如在表达式中 return 两个间接量,async 会把那个间接量透过 Promise.resolve() PCB成 Promise 第一类。

await

等候的是两个表达式,那个表达式的原始数据是 Promise 第一类或是其他值。假如它要到的并非两个 Promise 第一类,那 await 表达式的演算结论间接回到它要到的小东西。假如它要到的是两个 Promise 第一类,await 它会堵塞前面的标识符,等候 Promise 第一类 resolve,接着将 resolve 的值做为 await 表达式的演算结果回到。

2. async与await 与 promise 的差别

处置 then 链,以更典雅的形式将触发器的初始化以一类并行的形式手写。

// 标识符块1 // promise function rawPromise() { const time1 = 2; step1(time1) .then(time2 => step2(time2)) .then(time3 => step3(time3)) .then(result => { console.log(`result is ${result}`); }); } // async 与 await 修饰 async function uPpromise() { const time1 = 2; const time2 = await step1(time1); const time3 = await step2(time2); const result = await step3(time3); console.log(`with async and await result is${result}`); } function step1(time) { return new Promise((resolve, reject) => { resolve(time*time); }) } function step2(time) { return new Promise((resolve, reject) => { resolve(time*time); }) } function step3(time) { return new Promise((resolve, reject) => { resolve(time*time); }) } rawPromise(); // result is 256 uPpromise(); // with async and await result is 256

3. async 与 await 会堵塞标识符的执行吗? ️

举例在 vue 中的使用

// 标识符块2 async created() { console.log(async and await created–1–>); const res = await this.getData(); console.log(`async and await resolve–4–>${res}`); }, mounted() { console.log(async and await mounted–2–>); }, methods: { getData() { return new Promise((resolve, reject) => { console.log(async and await getData–3–>); resolve(yes) }) } },
async 与 await 是否阻塞进程?
输出执行结论

标识符块2中的 created 等同于以下标识符:

// 标识符块3 created() { console.log(async and await created–1–>); this.getData().then(res => { console.log(`async and await resolve–4–> ${res}`); }); },

结论:async 与 await 发生在其表达式的作用域中,不会堵塞js线程。

4. promise 为什么不会堵塞js线程? ️

js 单线程 js 是单线程的,因为假如有两个线程同时对同两个dom进行操作,则会产生不稳定。意味着标识符只能并行执行

2. promise 是 js 中的触发器操作的一类,js 的单线程特性如何实现触发器操作?

js 的宿主环境 浏览器/ node 是多线程的,这些宿主除了为js开辟两个主线程,考虑减少资源的浪费(网络请求,定时器和事件监听等任务会非常耗时),宿主为js开辟了其他的线程(http请求线程,浏览器定时触发器,浏览器事件触发线程),他们只是辅助js主线程,并不会去执行或是解析js标识符,以此保留了js的单线程特性又使得js可以做触发器操作。

3. 关于js事件循环的基本知识

执行栈先进后出。存放表达式初始化的栈结构。

js执行引擎执行全局的标识符时,首先创建全局的执行上下文,压入执行栈的顶部,引擎访问栈顶的执行上下文(浏览器的 JS 执行引擎总是访问栈顶的执行上下文),解析执行假如遇到新的表达式,则再次创建新的表达式执行上下文,并且把它压入执行栈的顶部,引擎访问栈顶的执行上下文执行表达式,表达式初始化完成后将当前表达式的执行上下文弹出栈,并等候垃圾回收。并行任务与触发器任务并行任务:在主线程上排队执行的任务,只有前两个任务执行完毕,才能执行后两个任务。

触发器任务:不进入主线程而进入”任务队列”(task queue)的任务,只有等主线程任务执行完毕,”任务队列”开始通知主线程,请求执行任务,该任务才会进入主线程执行。

触发器任务的类型:Events(click、resize、load、error等):javascript各种事件的执行都是触发器任务setTimeout、setInterval 定时器 特别的假如将setTimeout()的第二个参数设为0,就表示当前标识符执行完(执行栈清空)以后,立即执行(0毫秒间隔)指定的回调函queueMicrotask 执行微任务XMLHttpRequest(也就是 Ajax)requestAnimationFrame 类似于定时器,但是是以每一帧为单位fetch Fetch API 提供了两个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分MutationObserver 创建并回到两个新的 MutationObserver 它会在指定的DOM发生变化时被调用。Promiseasync function任务队列先进先出。js 引擎读取到触发器任务后,首先会将其挂起,当触发器任务有结论回到时,会将该回调表达式放至任务队列中。

不同的触发器操作添加到任务队列的时机也不同,具体参考如下:onclick 由浏览器内核的 DOM Binding 模块来处置,当事件触发的时候,回调表达式会立即添加到任务队列中。setTimeout 会由浏览器内核的 timer 模块来进行延时处置,当时间到达的时候,才会将回调表达式添加到任务队列中。ajax 则会由浏览器内核的 network 模块来处置,在网络请求完成回到之后,才将回调添加到任务队列中。宏任务与微任务宏任务:优先级:主代码块 > setImmediate > MessageChannel > setTimeout / setInterval

微任务:优先级:process.nextTick(node独有) > Promise(then/catch/finally) > MutationObserver(浏览器独有)4. js 事件循环

”事件“

任务队列中的每个任务实际上都对应着两个事件,DOM操作对应的是DOM事件,资源加载操作对应的是加载事件,而定时器操作可以看做对应两个“时间到了”的事件。

”循环“ 的机制

每一轮的实现都是 执行两个宏任务,宏任务结束后执行当前事件循环的所有微任务。

1)整个script首先做为一个宏任务执行,进入主线程上执行,形成两个执行栈;

2)宏任务执行过程中是并行标识符则马上执行,触发器标识符则挂起,当有回到结论时进入对应的队列(宏任务队列和微任务队列)

3)整个script做为首个宏任务执行完毕后,检查与否存在微任务 Microtasks ,假如存在则不停地执行,直至清空Microtask Queue

4)检查与否存在宏任务 Macrotasks,假如存在则执行Macrotask Queue的第两个宏任务,循环执行 2)~4)
async 与 await 是否阻塞进程?

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务