My project has a Swiper plug-in, in the Vue instance created (lifecycle-related) function, first asynchronously loading data with Ajax, and then initializing the Swiper Carousel plug-in, encountered a problem, Because dynamic Data loading results in Swiper initialization, it slides to the last item. My solution was to delay initialization with settimeout (), and then when I was learning es6, I find a better solution is to use Promise.then. However, there is no final only better, promise.then may have compatibility problems, you can use Vue Nexttick () method to solve.
The official description of the Nexttick () method is this:
Performs a deferred callback after the next DOM update loop ends. Use this method immediately after modifying the data to get the updated DOM.
It seems very suitable to solve my problem, that Nexttick () method is how to achieve it, whether including I have thought of the two solutions, with this thinking I looked at the Nexttick source: Vue-nexttick
I read the source before looking at some analytic nexttick articles, they generally describe nexttick use elegant downgrade way, the interior is actually the following three kinds of way callback:
1. Promise.then
2. Mutation.observe
3. settimeout (fn,0)
But when I look at the source, I found that the updated source code is so defined Nexttick:
1. Microtasks function
2. Macrotasks function
If you're confused about these two nouns, you can read this.
The explanation in the official source code is this:
Here we have async deferring wrappers using both micro and macro tasks.
In < 2.4 We used micro tasks everywhere, but there are some scenarios where micro tasks have too high a priority and fi Res in between supposedly sequential events (e.g. #4521, #6690) or even between bubbling of the same event (#6566). However, using macro tasks everywhere also has subtle problems when the state are changed right before repaint (e.g. #6813 -in transitions).
Here we use the Micro task by default, but expose a way to force the task when macro (needed. At event e.g handlers by V ON).
In short, we used to use Microtask in the past (<2.4 version), but his high priority could lead to problems (such as inserting some sequential event processing), but there was some trouble using macrotask completely. So we now default to use Microtask, and then force the use of macrotask when needed. Why use Microtask by default, as follows:
Depending on the HTML Standard, the UI will be rendered after each task runs out, so the data update is done in Microtask, and the current task ends with the latest UI. Conversely, if you create a new task to do the data update, the rendering will be done two times.
Understanding this knowledge, we will look at the source code in detail.
The main source of Microtask is the use of Promise.then
Determine Microtask defer implementation.
if (typeof Promise!== ' undefined ' && isnative (Promise)) {
Const P = promise.resolve ()
Microtimerfunc = () => {
p.then (flushcallbacks)
if (Isios) settimeout (noop)
}
} else {
Microtimerfunc = Macrotimerfunc
}
Macrotask is more complex, in order of Setimmediate->messagechannel->settimeout (fn,0)
//determine (macro) Task defer implementation.//Technically setimmediate should be the ideal C Hoice, but it ' s only available//in IE. The only polyfill that consistently queues of the callback after all DOM//events triggered in the same loop are by using Mes
Sagechannel. if (typeof setimmediate!== ' undefined ' && isnative (setimmediate)) {Macrotimerfunc = () => {Setimmediat
E (flushcallbacks)} "else If" (typeof Messagechannel!== ' undefined ' && isnative (messagechannel) | | Phantomjs messagechannel.tostring () = = ' [object Messagechannelconstructor] ') {Const CHANNEL = new Messagechanne L () const PORT = channel.port2 Channel.port1.onmessage = flushcallbacks Macrotimerfunc = () => {port.postmes Sage (1)}} else {macrotimerfunc = () => {settimeout (flushcallbacks, 0)}}
The
Annotation is clear and technically setimmediate () should be the ideal choice, but it can only be used in IE. After all DOM events that are triggered in the same loop, the only polyfill that queues the callback is the use of Messagechannel. This sets event handling for the Messagechannel object Port1, and then uses PORT2 to pass messages to Port1 to invoke. Note that settimeout (fn,0) still has a minimum 4ms delay even if the second argument is set to 0. (I have not used Messagechannel objects, the information on the Internet seems to be not much, if the reader has recommended information, please tell me in the comments ~
above is my summary, hope can help to encounter the same problem Meng new.