Vue 中Promise 中的方法无法执行,this作用域的问题简析

版权声明:本文为博主原创文章,转载请注明作者和出处,如有错误,望不吝赐教。 https://blog.csdn.net/weixin_41888813/article/details/85243197

Vue 中Promise 中的方法无法执行

需求:填写单子的页面,需要跳转去其他页面填写相关内容

解决:跳转前先将此页面填写的内容先保存,保存方法结束后再跳转

遇到的问题:前端提示this.submitEvent('NotBack');方法报错

代码一(错误)

            // 跳转
            doTypeResult(){
                let type = 0;
                let toPath = "";
                if(this.form.type == 1){
                    type = 1;
                }else if(this.form.type ==2){
                    type = 2;
                }else if(this.form.type == 3){
                    type = 3;
                }
                // 跳转前保存数据
                this.$refs.form.validate((valid) => {
                    if(valid){
                        new Promise(function(resolve,reject){
                            this.submitEvent('NotBack');
                            resolve();
                        }).then(() => {
                            toPath = '/config/view/'+ type+'?id=' + this.form.id;
                            this.$router.push({path: toPath});
                        }).catch(() => {
                            // this.$message.error("跳转出错")
                        });
                    }
                })
            },

解决:

代码二(正确),写法:将this,先赋给sel :let sel = this;

            // 跳转
            doTypeResult(){
                let type = 0;
                let toPath = "";
                let sel = this;
                if(this.form.type == 1){
                    type = 1;
                }else if(this.form.type ==2){
                    type = 2;
                }else if(this.form.type == 3){
                    type = 3;
                }
                // 跳转前保存数据
                this.$refs.form.validate((valid) => {
                    if(valid){
                        new Promise(function(resolve,reject){
                            sel.submitEvent('NotBack');
                            resolve();
                        }).then(() => {
                            toPath = '/config/view/'+ type+'?id=' + this.form.id;
                            this.$router.push({path: toPath});
                        }).catch(() => {
                            // sel.$message.error("跳转出错")
                        });
                    }
                })
            },

报错原因:

promsie里压根就读不到this,可以理解:取不到全局变量,作用域的问题,promise里的this和vue中的this指向不同,promise外面定义let sel = this ,然后在promise里使用 sel 就可以执行方法了


详解案例:vue2.0函数(箭头函数)的this作用域

在做vue项目时用到了axios,但是发现axios请求之后的回调函数里this并不指向当前vue实例,从而导致浏览器报错。

出错代码及结果:

  created : function(){
      axios.get('static/data.json').then(function(res){
          console.log(this)    //undefined
      this.user = res.data.user
   })
  }

普通函数代码改版(正确):

created : function(){
      var _this = this
      axios.get('static/data.json').then(function(res){
      console.log(this)    //undefined
      console.log(_this)   //VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
      _this.user = res.data.user
   })
  }

从以上结果来看,在created下的函数this指向的是当前创建的vue实例,而在这些函数内部使用例如axios与后台交互后回调函数的内部的this并非指向当前的vue实例;

若想拿到后台回传的数据更新data里的数据,不能在回调函数中直接使用this,而要用在外部函数定义的变量存储的this,也就是当前vue的实例。

箭头函数代码改版(正确):

created : function(){
      axios.get('static/data.json').then((res) => {
      console.log(this)      //VueComponent {_uid: 1, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}
      this.user = res.data.user
   })
  }

箭头函数相当于匿名函数,并且简化了函数定义。看上去是匿名函数的一种简写,但实际上,箭头函数和匿名函数有个明显的区别:箭头函数内部的this是词法作用域,由上下文确定。此时this在箭头函数中已经按照词法作用域绑定了。很明显,使用箭头函数之后,箭头函数指向的函数内部的this已经绑定了外部的vue实例了.


于是乎,我上面的方法可以改装为:

            // 跳转
            doTypeResult(){
                let type = 0;
                let toPath = "";
                if(this.form.type == 1){
                    type = 1;
                }else if(this.form.type ==2){
                    type = 2;
                }else if(this.form.type == 3){
                    type = 3;
                }
                // 跳转前保存数据
                this.$refs.form.validate((valid) => {
                    if(valid){
                        new Promise((resolve,reject) => {
                            this.submitEvent('NotBack');
                            resolve();
                        }).then(() => {
                            toPath = '/config/view/'+ type+'?id=' + this.form.id;
                            this.$router.push({path: toPath});
                        }).catch(() => {
                            // this.$message.error("跳转出错")
                        });
                    }
                })
            },

ES6的箭头函数来让代码在不升级 Vue2.0的情况下变得更加简洁和统一,可能需要关注作用域等其他的问题,

关于vue2.0使用ES6语法的箭头函数对this作用域的问题,

注意:Promise中执行的方法中,如果还嵌套了异步方法,可能会出现问题

后续再深入理解


参考来源于:

https://www.cnblogs.com/stella1024/p/7598541.html

https://blog.csdn.net/weixin_41888813/article/details/82882878

https://www.cnblogs.com/y896926473/articles/8709975.html

猜你喜欢

转载自blog.csdn.net/weixin_41888813/article/details/85243197