vue中遇到的函数执行顺序问题
vue中遇到的函数执行顺序问题
总结:vue中方法和方法间并未严格按照执行顺序执行的,可以使用async和await修饰符,或者使用Promise,使方法调用和执行是异步的。
在vue中的方法调用顺序是依次进行的,方法体内部也是依次执行的, 但是,两个方法体的执行顺序并不能严格控制,也就是说,并不一定是先执行完第一个方法后再执行后一个。
可以这样理解:任务表上有两个任务,它们按顺序排列,方法调用顺序是依次进行的就是将这两个任务按照顺序依次发布给工作者,但因为工作者不止一个,所以第一个任务发布给第一个人,第二个任务给第二个人;又因为任务的复杂性不一致,所以每个人完成对应任务的时间不同,可能会出现第二个任务先完成、第一个任务后完成的情况,即执行顺序并不能严格控制。也就是说方法是并行执行的。
举个例子:函数B中需要使用一个变量a,这个变量a一开始是没有值的,执行函数A后变量a才有值,所以要先执行函数A,再执行函数B。发送axios请求时,由于网络的不稳定,服务器的带宽不够或者处理函数较为复杂等情况,会导致函数A所需的时间开销大于函数B,函数B已经执行完,并结束了,函数A还没完成,这显然会造成错误。
例如:
export default {
name: 'xxx',
data() {
return {
a: [],
b: [],
T: 3,
}
},
methods: {
A() {
this.$axios.get(this.$httpUrl + '/a/list').then(res => res.data).then(
res => {
console.log('A')
if (res.code === 20041) {
this.a = res.data
}
}
)
},
B() {
this.$axios.get(this.$httpUrl + '/b/list').then(res => res.data).then(
res => {
console.log('B')
if (res.code === 20041) {
this.b = res.data
if (this.a.length === this.b.length) {
this.T = this.a.length
}
}
}
)
}
},
mounted() {
this.A()
this.B()
}
}
方法A 、B 都发送axios请求,B方法中使用了this.a.length,这意味着B方法依赖于A方法的结果。然而,由于两个请求是并行发起的,B方法可能在A方法完成之前执行,导致this.a.length的值不正确。,虽然在mounted()中的顺序是先执行A,再执行B,但通过控制台可以发现,输出并不固定。进一步推断:在这种情况下,如果函数B中需要用到 通过函数A得到的值 时,显然会产生错误。
哪怕将函数A放在函数B中(代码如下),也并不会有作用。
export default {
name: 'xxx',
data() {
return {
a: [],
b: [],
T: 3,
}
},
methods: {
A() {
this.$axios.get(this.$httpUrl + '/a/list').then(res => res.data).then(
res => {
console.log('A')
if (res.code === 20041) {
this.a = res.data
}
}
)
},
B() {
this.A() // 期望在执行方法`B`时,先执行方法`A`
this.$axios.get(this.$httpUrl + '/b/list').then(res => res.data).then(
res => {
console.log('B')
if (res.code === 20041) {
this.b = res.data
if (this.a.length === this.b.length) {
this.T = this.a.length
}
}
}
)
}
},
mounted() {
this.B()
}
}
只不过之前是函数A和函数B不严格地按照顺序执行,而现在是在函数B中,方法A和axios请求方法不严格地按照顺序执行。
为避免出现这种情况,可以使用async和await修饰符,使方法调用和执行是异步的。
代码如下:
export default {
name: 'xxx',
data() {
return {
a: [],
b: [],
T: 3,
}
},
methods: {
A() {
this.$axios.get(this.$httpUrl + '/a/list').then(res => res.data).then(
res => {
console.log('A')
if (res.code === 20041) {
this.a = res.data
}
}
)
},
async B() {
await this.A()
this.$axios.get(this.$httpUrl + '/b/list').then(res => res.data).then(
res => {
console.log('B')
if (res.code === 20041) {
this.b = res.data
if (this.a.length === this.b.length) {
this.T = this.a.length
}
}
}
)
}
},
mounted() {
this.B()
}
}
async表明该函数是异步函数。
await表示等待 —— await后面的函数运行完并且有了返回结果之后,才继续执行下面的代码。
注意: await关键字只能放到async函数里面

浙公网安备 33010602011771号