-
Notifications
You must be signed in to change notification settings - Fork 4.8k
/
Copy pathnext-tick.ts
48 lines (40 loc) · 1.43 KB
/
next-tick.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import { Current } from './current'
import { TaroRootElement } from './dom/root'
import env from './env'
import type { TFunc } from './interface'
const TIMEOUT = 100
export const nextTick = (cb: TFunc, ctx?: Record<string, any>) => {
const beginTime = Date.now()
const router = Current.router
const timerFunc = () => {
setTimeout(function () {
ctx ? cb.call(ctx) : cb()
}, 1)
}
if (router === null) return timerFunc()
const path = router.$taroPath
/**
* 三种情况
* 1. 调用 nextTick 时,pendingUpdate 已经从 true 变为 false(即已更新完成),那么需要光等 100ms
* 2. 调用 nextTick 时,pendingUpdate 为 true,那么刚好可以搭上便车
* 3. 调用 nextTick 时,pendingUpdate 还是 false,框架仍未启动更新逻辑,这时最多轮询 100ms,等待 pendingUpdate 变为 true。
*/
function next () {
const pageElement: TaroRootElement | null = env.document.getElementById<TaroRootElement>(path)
if (pageElement?.pendingUpdate) {
if (process.env.TARO_PLATFORM === 'web') {
// eslint-disable-next-line dot-notation
pageElement.firstChild?.['componentOnReady']?.().then(() => {
timerFunc()
}) ?? timerFunc()
} else {
pageElement.enqueueUpdateCallback(cb, ctx)
}
} else if (Date.now() - beginTime > TIMEOUT) {
timerFunc()
} else {
setTimeout(() => next(), 20)
}
}
next()
}