We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
为了协调用户输入, 网络请求, 事件,渲染,和JavaScript脚本的运行, 浏览器引入事件循环,多个同源的窗口共享一个事件循环.
js的执行是单线程的, 如果需要进行异步的任务, 那么它会确定这是一个宏任务还是一个微任务, 如果是微任务则会进入微任务的队列, 如果是宏任务则会进宏任务对应事件源的队列.js的对异步任务的执行过程则是不断的轮询这2个队列, 直到2个队列为空.
官方文档事件循环https://html.spec.whatwg.org/multipage/webappapis.html#event-loops
setTimeout(()=>{ console.log("timeout1"); Promise.resolve().then(()=>{ console.log("promise1"); }); }); Promise.resolve().then(()=>{ console.log("promise2"); setTimeout(()=>{ console.log("timeout2"); }); }); // promise2 // timeout1 // promise1 // timeout2
执行的主要过程是,
根据HTML 标准,一轮事件循环执行结束之后,下轮事件循环执行之前开始进行UI render。即:
setTimeout(()=>{console.log(1)}, 0); // 1 requestAnimationFrame(()=>console.log(2)); // 2 // 那为什么大多数时候是1,2, 偶尔会2,1呢; 而且把1,2行的顺序反过来, // 代码的结果也是和原来的一样, 只是偶尔会2,1
requestAnimationFrame 的相关知识 https://javascript.ruanyifeng.com/htmlapi/requestanimationframe.html
let t = 0 , timer = null; function loop(){ var timestart = Date.now(); var timeEnd = 0; timer = setTimeout(function(){ if(t++ == 200) return; timeEnd = Date.now(); console.log(timeEnd - timestart, timestart, timeEnd); loop(); }, 0); } loop();
为什么有的结果都是1ms ,2ms. 但是多数时候是4ms, 5ms, 6ms, 这是执行的时间只能是一个大概的时间, 并不十分准确. 浏览器的时钟刻度就是4ms, 每隔4ms, 就会从系统处同步时钟, 这时再去检查事件循环队列中,是否有事件可以触发. 同时如果chrome的浏览器有多个标签窗口那么非当前标签js线程会挂起, 但是不会停止ui线程的渲染, 切换到该进程的时候, 会需要一定的唤醒成本.比如刚唤醒的时候执行的setTimeout时钟差不多一个1000ms左右的时钟同步刻度.
let i = 0; while(i++< 10000){ loop(); } function loop(){ setTimeout(function(){ console.log("timeout"); }); requestAnimationFrame(function(){ console.log("request") }); }
前面我们说setTimeout的时间检查精度最小是4ms, 以一个60hz的刷新频率的显示器, 那么1000/60 = 16.66ms 的动画会集合到一个渲染周期内, setTimeout 最小是4ms, 怎么也应该会出现setTimeout在前, requestAnimationFrame在后的情况吧? 但是真实打印的情况却是, requestAnimationframe动作先执行, setTimeout后执行, 并且所有的requestAnimationFrame的队列全部完成后, 才开始执行setTimeout,
这不是渲染ui进程渲染后的值, 而是在内存中修改后的值, vue的$nextTick有可能是宏任务, 也有可能是微任务, 看浏览器的运行环境支持程度, 目前是先检查是否支持mutationObserver, 然后检查ie的setImmediate,最后才是 我们修改一个指令后,在代码后面天界 this.$nextTick(callback); callback的内容
vm.a = 1; // 添加一个微任务, 获取节点信息. vm.$nextTick(function(){ document.getElementById('#a').textContent; // 这时获取的节点信息, 实际是ui线程未渲染前的节点信息, 但是在内存中已经被修改了, 因为vm.a = 1; 触发了对象setter的回调,这里可以理解为同步的修改. }); // ... // 触发属性监听器的回调, 修改dom信息, 添加一个宏任务(UI渲染)
monitoring process线程是浏览器事件循环模型中的一个辅助线程, 如果是node, 那么这个监听由libv的事件循环机制提供, 用来监听javascript的执行栈是否为空, 如果为空, 那么会去检查微任务列表出栈, 微任务进入主执行栈, 执行, 如果执行的过程产生微任务, 会把微任务放到微任务列表队尾, 直到清空了微任务的列表, 再去执行并宏任务列表.
微任务、宏任务与Event-Loop https://juejin.im/post/5b73d7a6518825610072b42b 从event loop规范探究javaScript异步及浏览器更新渲染时机 aooy/blog#5 官方的事件循环执行模型 https://html.spec.whatwg.org/multipage/webappapis.html#event-loop-processing-model
The text was updated successfully, but these errors were encountered:
No branches or pull requests
js 浏览器的事件循环 event-loop
事件循环
为了协调用户输入, 网络请求, 事件,渲染,和JavaScript脚本的运行, 浏览器引入事件循环,多个同源的窗口共享一个事件循环.
js的执行是单线程的, 如果需要进行异步的任务, 那么它会确定这是一个宏任务还是一个微任务, 如果是微任务则会进入微任务的队列, 如果是宏任务则会进宏任务对应事件源的队列.js的对异步任务的执行过程则是不断的轮询这2个队列, 直到2个队列为空.
宏任务
微任务
一段代码
为什么会是这个顺序?
执行的主要过程是,
根据HTML 标准,一轮事件循环执行结束之后,下轮事件循环执行之前开始进行UI render。即:
问题
requestAnimationFrame 和setTimeout 都属于宏任务阵列的函数, 那么为什么requestAnimationFrame总会比setTimeout先执行?
关于setTimeout 的最少4ms的延迟? 你确定吗?
为什么有的结果都是1ms ,2ms. 但是多数时候是4ms, 5ms, 6ms, 这是执行的时间只能是一个大概的时间, 并不十分准确.
浏览器的时钟刻度就是4ms, 每隔4ms, 就会从系统处同步时钟, 这时再去检查事件循环队列中,是否有事件可以触发.
同时如果chrome的浏览器有多个标签窗口那么非当前标签js线程会挂起, 但是不会停止ui线程的渲染, 切换到该进程的时候, 会需要一定的唤醒成本.比如刚唤醒的时候执行的setTimeout时钟差不多一个1000ms左右的时钟同步刻度.
requestAnimationFrame总会比setTimeout的先执行
前面我们说setTimeout的时间检查精度最小是4ms, 以一个60hz的刷新频率的显示器, 那么1000/60 = 16.66ms 的动画会集合到一个渲染周期内, setTimeout 最小是4ms, 怎么也应该会出现setTimeout在前, requestAnimationFrame在后的情况吧? 但是真实打印的情况却是, requestAnimationframe动作先执行, setTimeout后执行, 并且所有的requestAnimationFrame的队列全部完成后, 才开始执行setTimeout,
vue nextTick 不是微任务吗? 为啥可以获取到变化后的值
JavaScript运行过程中的 monitoring process
The text was updated successfully, but these errors were encountered: