^finished异步最终解决方案,
如何将异步请求同步化执行?
现在有这么一串代码:
js
import axios from 'axios';
export default {
methods: {
GetJoke() {
let isReturn = '初始值'
axios.get('https://autumnfish.cn/api/joke').then(res => {
if (res.data.length > 10) {
isReturn = true
console.log('isReturn的值改变了~', isReturn) // true
}
})
console.log(isReturn) // 初始值
},
}
}
import axios from 'axios';
export default {
methods: {
GetJoke() {
let isReturn = '初始值'
axios.get('https://autumnfish.cn/api/joke').then(res => {
if (res.data.length > 10) {
isReturn = true
console.log('isReturn的值改变了~', isReturn) // true
}
})
console.log(isReturn) // 初始值
},
}
}
打印结果发现,isReturn的值仍然是"初始值",这是因为接口时异步的,也就是打印isReturn的时候,接口返回值还没获得到。
那么,如何等待接口返回值到达之后,再执行后续代码呢?
在接口中 then()
里return行不行?
js
import { getData } from './xxx/xxx.js'
export default {
created() {
console.log(this.confirm()) // promise对象
},
methods: {
confirm(){
getData().then(res => {
return true
})
}
}
}
import { getData } from './xxx/xxx.js'
export default {
created() {
console.log(this.confirm()) // promise对象
},
methods: {
confirm(){
getData().then(res => {
return true
})
}
}
}
打印得到一个promise对象,不行,将接口方法return出去试试:
js
import { getData } from './xxx/xxx.js'
export default {
created() {
console.log(this.confirm()) // promise对象
},
methods: {
confirm(){
return getData().then(res => { // 在这里加上return
return true
})
}
}
}
import { getData } from './xxx/xxx.js'
export default {
created() {
console.log(this.confirm()) // promise对象
},
methods: {
confirm(){
return getData().then(res => { // 在这里加上return
return true
})
}
}
}
仍然不管用,getData()
return出来的结果是一个promise对象。
就算加上了 await
、 async
,抱歉,还是不行。
想要的 ture
在promise对象里面,官方文档里提到了是取不到的,想要等待接口返回值到达后执行后续操作,得将后续代码放到 then()
里面。
看来不能采取return的方案,怎么办?
异步最终解决方案, async
和 await
仅需给methods里的方法和axios方法加上 async
和 await
就可以等接口返回值到达之后再执行后续代码。Option式API的方法格式要改一下。
js
import axios from 'axios';
export default {
methods: {
GetJoke: async function() {
let isReturn = '初始值'
await axios.get('https://autumnfish.cn/api/joke').then(res => {
if (res.data.length > 10) {
isReturn = true
console.log('isReturn的值改变了~', isReturn) // true
}
})
console.log(isReturn) // true
},
}
}
import axios from 'axios';
export default {
methods: {
GetJoke: async function() {
let isReturn = '初始值'
await axios.get('https://autumnfish.cn/api/joke').then(res => {
if (res.data.length > 10) {
isReturn = true
console.log('isReturn的值改变了~', isReturn) // true
}
})
console.log(isReturn) // true
},
}
}
如果在别的接口里调用包裹axios接口的GetJoke()方法,怎么办呢?
给methods中的方法调整一下,给 包裹接口API的方法
前面加上 async
,给调用 包裹这个加上async的方法
的方法也加上 async
。
js
import axios from 'axios';
export default {
methods: {
GetJoke: async function () {
// ...开始
await axios.get('https://autumnfish.cn/api/joke').then(res => {
console.log(res)
})
// ...其他操作
},
waitGetJoke: async function () {
// ...开始
await this.GetJoke()
// ...其他操作
},
}
}
import axios from 'axios';
export default {
methods: {
GetJoke: async function () {
// ...开始
await axios.get('https://autumnfish.cn/api/joke').then(res => {
console.log(res)
})
// ...其他操作
},
waitGetJoke: async function () {
// ...开始
await this.GetJoke()
// ...其他操作
},
}
}
应用场景有哪些?
比如:我需要以一个数组的每个元素作为参数,循环调用某个接口,当循环到某个接口时,返回值达到了要求的条件,跳出循环
html
<template>
<div>
<el-button :loading="loading" type="primary" @click="waitGetJoke()">waitGetJoke</el-button>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
isReturn: false,
loading: false,
}
},
methods: {
GetJoke: async function() {
console.log('开始调用接口...')
await axios.get('https://autumnfish.cn/api/joke').then(res => {
console.log(res.data.length)
if (res.data.length > 100) {
this.isReturn = true
}
})
console.log('...接口调用完毕')
},
waitGetJoke: async function() {
this.isReturn = false
this.loading = true
console.log('开始循环...')
for (let i = 0; i < 10; i++) {
await this.GetJoke()
if (this.isReturn) {
console.log('侦测到长度大于100,break')
break
}
}
this.loading = false
console.log('...结束循环')
},
}
}
</script>
<template>
<div>
<el-button :loading="loading" type="primary" @click="waitGetJoke()">waitGetJoke</el-button>
</div>
</template>
<script>
import axios from 'axios';
export default {
data() {
return {
isReturn: false,
loading: false,
}
},
methods: {
GetJoke: async function() {
console.log('开始调用接口...')
await axios.get('https://autumnfish.cn/api/joke').then(res => {
console.log(res.data.length)
if (res.data.length > 100) {
this.isReturn = true
}
})
console.log('...接口调用完毕')
},
waitGetJoke: async function() {
this.isReturn = false
this.loading = true
console.log('开始循环...')
for (let i = 0; i < 10; i++) {
await this.GetJoke()
if (this.isReturn) {
console.log('侦测到长度大于100,break')
break
}
}
this.loading = false
console.log('...结束循环')
},
}
}
</script>
同样的,此例可以通过其他方案实现,比如直接在接口的then中跳出循环。但是当业务逻辑更加复杂的时候,放到then中就没那么好实现了。