Vue.js开发:Promise内部setInterval中this指向异常的解决方法咨询
解决Vue.js中Promise+setInterval的this指向问题
嘿,我瞅了你的代码,问题根源就在Promise构造函数的作用域绑定上!咱们一步步来捋清楚:
问题出在哪?
你写的new Promise(function(resolve) { ... })用了普通函数作为构造参数,这个普通函数内部的this并不是Vue实例(严格模式下是undefined)。虽然你在setInterval里用了箭头函数,但它继承的是这个普通Promise函数的this,自然就找不到this.$store了。另外还有个小坑:你把setTimeout放在了setInterval的回调里,这会导致每10毫秒就创建一个新的20秒超时,最后一堆定时器同时触发,完全不符合预期。
修复方案
直接上修改后的代码,我给你标了关键改动:
methods: { ...mapActions(['setCredentials']), doLogin() { console.log('credentials ' + this.username, this.password); this.$store.dispatch('connect', { username: this.username, password: this.password, }); this.checkResult() .then((interval) => { // 这里原来的vm没定义,换成this就好 this.$f7router.navigate('/favorites'); }) .catch((error) => { // 别忘了处理超时错误,给用户点反馈 console.error('登录超时,请重试:', error); // 这里可以加个提示框之类的交互 }); }, checkResult() { // 关键1:把Promise构造函数换成箭头函数,继承Vue实例的this return new Promise((resolve, reject) => { const id = setInterval(() => { const condition = this.$store.state.isConnected; if (condition) { clearInterval(id); resolve(id); } }, 10); // 关键2:把setTimeout移到外面,只创建一次超时定时器 setTimeout(() => { clearInterval(id); // 用Error对象传递错误信息更规范 reject(new Error('连接超时')); }, 20000); }); } }
为什么这样有效?
- 箭头函数不会创建自己的
this上下文,它会继承外层作用域的this。当Promise构造函数用箭头函数时,它的this就是Vue实例,所以setInterval里的箭头函数就能正确访问this.$store了。 - 把
setTimeout移到Promise构造函数的顶层,确保只会创建一次超时定时器,到点就清理轮询的setInterval并拒绝Promise,逻辑更合理。
内容的提问来源于stack exchange,提问作者Rasim Avcı
相关产品推荐
相关产品推荐

