重温V8引擎事件循环,反思异步带来的现代化开发壁障
孔夫子有云:温故而知新。
不断的回味以前对于知识的理解,不断的实践,不断的推翻,逆向思考,新的知识就会慢慢浮现。
一分钟理解微任务、宏任务
宏任务:
DOM事件setTimeoutsetInterval- 脚本
I/O
微任务
promiseGC- 等等
当然,requestIdleCallback和requestAnimationFrame不属于task,它们是浏览器渲染过程的一步,和task/microtask的执行是分离的。
小二,先上一道烂大街的面试题!
讲述下事件循环:
1 | console.log('同步代码开始') |
答案公布:
同步代码开始
3
2
同步代码结束
4
第一步:整个代码块被扔进了宏任务中;
第二步:console同步代码被放入执行栈中开始执行,打印 同步代码开始
第三步:Promise构造函数是同步代码,压栈执行,打印3、2
第四步:console同步代码被放入执行栈中开始执行,打印 同步代码结束
第五步:宏任务代码执行完毕,检查是否有微任务代码可以执行。
第六步:async函数中的出现 await 后,之后的代码被放入Promise.then中,微任务队列开始执行。
参考链接
【1】从一道题浅说js事件循环(https://github.com/dwqs/blog/issues/61 )
【2】requestIdleCallback和requestAnimationFrame详解(https://www.cnblogs.com/cangqinglang/p/13877078.html )
反思壁障

由快慢async发出的思考
【1】slow-async-await(https://mdn.github.io/learning-area/javascript/asynchronous/async-await/slow-async-await.html)
【2】fast-async-await(https://mdn.github.io/learning-area/javascript/asynchronous/async-await/fast-async-await.html)
接下来,我们慢慢食用代码:
— timeoutPromise —
1 | function timeoutPromise(interval) { |
— 计时程序 —
1 | let startTime = Date.now(); |
— slow-async-await —
1 | async function timeTest() { |
— fast-async-await —
1 | async function timeTest() { |
看下MDN的解释:

这句同时启动它们的关联进程可能很难理解,其实不难,理解了async await—> promise后,原理一目了然:
1 | // 转换前 |
起因就是因为async将异步代码真的同步化了,导致同步代码也进入了异步等待中,所以使用变量保存Promise的执行状态,实际上可以理解为并行执行了异步的构造任务。
参考链接
【1】MDN(https://developer.mozilla.org/zh-CN/docs/Learn/JavaScript/Asynchronous/Async_await )
【2】js异步梳理:1.从浏览器的多进程到JS的单线程,理解JS运行机制(https://www.cnblogs.com/hezhi/p/10484884.html )
【3】为什么要在变量中存储Promise对象?(https://www.debugcn.com/article/53568001.html )
由useState闭包引发的思考与如何跳出闭包壁障
国际惯例,先扔一道烂大街的面试题:
React 闭包陷阱如何用 useReducer 解决?
---- 阿里云前端面试
直接上代码地址:https://imweb.io/topic/5cd845cadcd62f86299fcd76
问题原因请慢慢食用,解决方案如下:
useState的实现原理就是利用了闭包。
官方原话是:useEffect、useMemo、useCallback都是自带闭包的。每一次组件的渲染,它们都会捕获当前组件函数上下文中的状态(state, props),所以每一次这三种hooks的执行,反映的也都是当前的状态,你无法使用它们来捕获上一次的状态。
- 怎么解决呢?
useReducer 的 dispatch 可以在全局中保持唯一不变的引用,所以用它更新一定能操作最新的值,其次是借助 setState 使用函数更新,更新当前闭包 作用域的旧值,还可以借助 useRef 在外围拿到最新值,因为对象引用不变,所以也能拿到最新值,其次是添加依赖项。


End
以上就是今日份的知识总结,请君慢用~~~