Vue 2 路由跳转至目标页面后promise无法正常resolve问题咨询
问题成因
- 浏览器的
window.load事件仅在整页资源全部加载完成时触发一次,前端路由跳转属于软路由切换,不会触发页面重载,也就不会再次触发window.load事件 - 刷新页面进入时,组件mounted执行时机早于window.load触发时机,所以绑定的监听函数可以正常执行;但路由跳转进入页面时,window.load早已经在站点首次加载时就触发完毕,后续再绑定的load事件监听永远不会执行,导致Promise一直处于pending状态,await后的代码始终不会运行
可行解决方案
方案1:兼容已加载状态修改getPosition方法
优先判断当前页面加载状态,若已经加载完成直接resolve,否则再绑定load事件监听,兼容刷新和路由跳转两种场景:
getPosition() { return new Promise((resolve, reject) => { // 先判断当前文档是否已经加载完成 if (document.readyState === 'complete') { console.log("window already loaded"); resolve(); return; } // 未加载完成再绑定监听事件 window.addEventListener("load", () => { console.log("window is loaded"); resolve(); }); }); },
方案2:简化逻辑移除不必要的load监听
如果你的业务逻辑不需要等待图片、字体等所有静态资源加载完成,仅需要DOM渲染完成即可执行,可直接去掉load事件监听:
getPosition() { console.log("logic execute"); return Promise.resolve(); },
方案3:全局预存load状态供多页面复用
如果站点多个页面都需要依赖load状态,可在入口文件提前监听一次事件,将状态存在全局变量中,后续所有页面调用直接读取状态即可:
// 入口文件main.js中提前监听 window._isWindowLoaded = false; window.addEventListener('load', () => { window._isWindowLoaded = true; }); // 组件内getPosition方法 getPosition() { return new Promise((resolve) => { if (window._isWindowLoaded) { resolve(); return; } const checkLoaded = () => { if (window._isWindowLoaded) { window.removeEventListener('load', checkLoaded); resolve(); } } window.addEventListener('load', checkLoaded); }) }
内容的提问来源于stack exchange,提问作者DemiA
相关产品推荐
相关产品推荐

