前言
【vue-router源码】系列文章将带你从0开始理解vue-router
的具体实现。该系列文章源码参考vue-router v4.0.15
。
源码地址:https://github.com/vuejs/router
浏览该文章的前提是你最好理解vue-router
的根本应用,如果你没有应用过的话,可通过vue-router官网学习下。
该篇文章将剖析isReady
的实现。
应用
router.isReady() .then(() => { // 胜利 }) .catch(() => { // 失败 })
isReady
isReady
不承受任何参数。如果路由器曾经实现了初始化导航,那么会立刻解析Promise
,相同如果还没有实现初始化导航,那么会将resolve
和reject
放入一个数组中,并增加到一个列表中,期待初始化导航实现进行触发。
let readyHandlers = useCallbacks<OnReadyCallback>()function isReady(): Promise<void> { // ready为true并且以后路由不是初始路由,导航曾经初始化结束,立刻解析promise if (ready && currentRoute.value !== START_LOCATION_NORMALIZED) return Promise.resolve() // 相同,会将resolve、reject存入一个列表 return new Promise((resolve, reject) => { readyHandlers.add([resolve, reject]) })}
在之前解析的push
过程中,无论过程中是否有错误信息,都会执行一个markAsReady
函数。在markAsReady
中会将isReady
处理函数进行触发,触发结束后,会将列表清空。
function markAsReady<E = any>(err?: E): E | void { if (!ready) { // 如果存在err,阐明还未筹备好,如果不存在err,那么阐明初始化导航曾经实现,ready变为true,之后就不会再进入这个分支 ready = !err // 设置popstate监听函数 setupListeners() // 触发ready处理函数,有谬误执行reject(err),没有执行resolve() readyHandlers .list() .forEach(([resolve, reject]) => (err ? reject(err) : resolve())) // 执行完,清空列表 readyHandlers.reset() } return err}