Vue3+uni-app异步请求终极指南
在前端开发(特别是 Vue3 + uni-app)里,我们经常需要去调用接口拿数据。但接口是网络请求,它不是立即就能返回结果的,而是异步的。这时候,async 和 await 就是我们最常用的“神器”。
1. 为什么需要 async/await?
以前我们写异步代码,一般长这样:
uni.request({
url: '/api/article/latest',
success: (res) => {
console.log('拿到数据', res)
},
fail: (err) => {
console.error('网络错误', err)
}
})
看上去没问题,但如果请求很多,就会变成“回调地狱”,代码层层嵌套,非常难看。
回调写法
uni.request({
url: '/api/a',
success: (resA) => {
uni.request({
url: '/api/b',
success: (resB) => {
console.log('先拿到A,再拿到B')
}
})
}
})
而 async/await 的出现,就是让异步代码写起来像“同步”一样直观:
async function fetchData () {
try {
const res = await uni.request({ url: '/api/article/latest' })
console.log('拿到数据', res)
} catch (e) {
console.error('网络错误', e)
}
}
2. async 和 await 到底是什么?
-
async:用来声明一个函数是“异步函数”。-
作用:这个函数的返回值一定是一个
Promise。
-
-
await:只能在async函数里用,意思是“等这个 Promise 执行完再往下走”。
换句话说,await 会让代码“停一下”,直到结果回来。
但注意:它只是暂停当前函数,不会卡死整个页面。
3. 在 uni-app 里怎么用?
最常见的场景:请求后端接口。
async function fetchLatestNotices () {
try {
const res = await uni.request({
url: '/api/article/latest',
method: 'GET',
data: { category: 3, limit: 2 }
})
// 1. HTTP 状态码
if (res.statusCode !== 200) throw new Error('网络异常')
// 2. 后端业务状态码(假设后端返回 { code, msg, data })
if (res.data.code !== 200) throw new Error(res.data.msg || '接口出错')
// 3. 取业务数据
const list = res.data.data || []
console.log('业务数据', list)
} catch (err) {
console.error('请求失败', err)
}
}
这样写逻辑特别清晰:
-
先判断 HTTP 层面有没有成功
-
再判断后端的业务返回是否成功
-
最后取出真正的数据
res的解析
1. 网络层(uni.request 的原始返回)
const res = await uni.request({ url: '/api/article/latest' })
这时 res 的结构大致是:
{
data: {...}, // ← 后端返回的整个响应体
statusCode: 200, // HTTP 状态码
header: {...},
errMsg: "request:ok"
}
statusCode 是 HTTP 状态码,由网络层返回。
2. 后端 Ajax 返回的结构
常见的后端接口会返回类似
{
"code": 200,
"msg": "操作成功",
"data": [
{ "id": 1, "title": "通知1" },
{ "id": 2, "title": "通知2" }
]
}
这时:
-
res.data就是上面整个 JSON 对象。 -
res.data.data才是业务真正的数据数组。
4. 生命周期里调用
在 Vue3 + uni-app 里,通常在生命周期调用:
import { onMounted, onShow } from '@dcloudio/uni-app'
onMounted(() => {
fetchLatestNotices() // 页面第一次加载时执行
})
onShow(() => {
fetchLatestNotices() // 每次切回页面时再刷新
})
5. 最佳实践:封装请求方法
为了避免每个地方都写一堆重复的判断,我们可以封装一个 request 工具函数:
// utils/request.js
export async function request (options) {
const res = await uni.request(options)
if (res.statusCode !== 200) throw new Error('网络错误')
if (res.data.code !== 200) throw new Error(res.data.msg || '接口错误')
return res.data.data
}
以后用的时候,只要写:
import { request } from '@/utils/request.js'
async function fetchNotices () {
try {
const list = await request({ url: '/api/article/latest', method: 'GET' })
console.log('拿到数据', list)
} catch (e) {
uni.showToast({ title: e.message, icon: 'none' })
}
}
6. 总结
-
async标记异步函数,await等待 Promise。 -
await让异步逻辑看起来像同步执行,代码更清晰。 -
在 uni-app 里,常见用法就是配合
uni.request来写接口调用。 -
建议统一封装请求函数,避免重复写“HTTP 状态码 + 业务状态码”的判断逻辑。
一句话记住:没有 async/await,你写异步就像走迷宫;有了它,代码就像一条直路。
async/await 只是“语法糖”,并不会加快影响速度,真正影响速度的,是你选择“顺序请求”还是“并发请求”
更多推荐


所有评论(0)