标题实在不知道怎么写了,感觉怎么写都有点不太准确。简单描述下场景。
比如在hybrid开发时,使用JsBridge提供操作给js,如果提供的操作需要在web页面加载完立即调用(如埋点日志之类的),可能调用失败,即使是在window.onload里调用也未必能获取到,而系统又没有提供准确的监听事件来判断,所以通常的做法可能会是这样的:
1 2 3
| setTimeout(() => { }, 600)
|
延迟一小段时间再去执行,这种方法虽然可行,但总觉得很蛋疼。因为虽然JsBridge不会立即加载完成,但不同的系统下或由于缓存的情况下,加载时间各不相同。
为了能较为准确的检测到其是否加载完成,也只好勉为其难的使用定时器去不停地检测。
1 2 3 4 5 6 7
| let timer = setInterval(() => { if (typeof window.jsBridgeAction === 'function') { clearInterval(timer) } }, 50)
|
也还好,在此提供一种封装方法,用起来跟onload事件监听似的,皆大欢喜。
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
| const readyPromise = (variableName, { rate = 50, timeout = 1500 } = {}) => { if (typeof variableName !== 'string') { throw new Error('The first argument should be a string') }
let rateTimer, overTimer
const _GLOBAL = new Function('return this')()
const _clearTimer = () => { clearInterval(rateTimer) clearTimeout(overTimer) }
return new Promise((resolve, reject) => { if (_GLOBAL[variableName]) { resolve() return }
rateTimer = setInterval(() => { if (_GLOBAL[variableName]) { _clearTimer() resolve() } }, rate)
overTimer = setTimeout(() => { _clearTimer() reject(new Error('timeout')) }, timeout) }) }
readyPromise('jsBridgeAction').then(() => { }).catch(e => { console.error(e) })
|
也可以直接使用ready-promise库,使用方法稍有不同:
1 2 3 4 5 6 7 8
| npm i ready-promise -S ``
```javascript import readyPromise from 'ready-promise' readyPromise(() => { return typeof window.jsBridgeAction === 'function' }).then(() => {}).catch(e => {})
|