You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constp=Promise.resolve()microTimerFunc=()=>{p.then(flushCallbacks)// in problematic UIWebViews, Promise.then doesn't completely break, but// it can get stuck in a weird state where callbacks are pushed into the// microtask queue but the queue isn't being flushed, until the browser// needs to do some other work, e.g. handle a timer. Therefore we can// "force" the microtask queue to be flushed by adding an empty timer.if(isIOS)setTimeout(noop)}
nextTick的实现本质是采用了js Event Loop的知识实现。
其使用场景在赋值state后使用,目的是等待watcher触发更新界面后调用回调。本文旨在理解Event Loop的基础上查看vue nextTick的实现,以便于在使用过程中更好的解决问题。
nextTick 伪代码
然后再就是定义macroTimerFunc和microTimerFunc时所涉及的点
在ie中支持setImmediate,非ie中,都是使用
MessageChanel
发送消息来保持callback始终以队列的形式调用的。除非二者不支持,最后才用的setTimeout保底。用Promise模拟的,但是在iOS UIWebViews中有个bug,Promise.then并不会被触发,除非浏览器中有其他事件触发,例如处理setTimeout。所以手动加了个空的setTimeout
如果Promise都不支持,那microTimerFunc = macroTimerFunc
疑问
w3c html规范中定义了setTimeout的默认最小时间为4ms,而嵌套的timeout表现为10ms,也就是说即使你赋值0,而实际却不是。再由于,setTimeout的时间,会受到任务队列的影响(或其它原因?)其实际时间远大于10ms,这或许就是vue不优先使用setTimeout的原因吧。
此处参考
vue内置了一个函数withMacroTask,当组件的state变化时,就会使用task,其它默认都是microTask
推荐阅读
Tasks, microtasks, queues and schedules
最后,注释中的2个问题#4521, #6690,欢迎一起讨论。
The text was updated successfully, but these errors were encountered: