问题描述
最近遇到一个奇怪的需求,和大家分享一下
假设后端返回一个数组,数组数据如下:
let arr = [
{
name: '孙悟空',
id: '111',
age: null
},
{
name: '猪八戒',
id: '222',
age: null
},
{
name: '沙和尚',
id: '333',
age: null
},
{
name: '唐僧',
id: '444',
age: null
},
{
name: '白龙马',
id: '555',
age: null
},
]
- 注意,这里并没有直接返回每一项的年龄
- 每一项的年龄,需要前端再调用一个接口,把名字作为参数,再去请求某个人的年龄
- 有的朋友问,那为啥不把年龄通过sql语句,查出来,直接赋值到数组List中的age字段上?
- 正常来说,是需要这样做的,不过某些情况下(很少情况)
- 的确是只能再发请求,专门用于获取年龄字段数据了
所以:
- 当我们获取到这个数组以后,需要循环发请求,
- 拿着名字,去获取对应年龄
接口函数
function getAge(name) {
return new Promise((resolve, reject) => {
axios.get(`http://ashuai.work/api/getAge?name=${name}`).then((res) => {
let age = res.data.data.age
console.log(`获取 ${name} 的年龄为: ${age}`);
resolve(age)
}).catch((err) => {
reject(err)
})
})
}
示例:
{
"code": "0",
"message": "成功",
"data": {
"age": 500 // 88
}
}
使用Promise.all搭配map循环
- 注意,这里不能使用forEach循环,因为Promise.all需要接收一个数组
- 而forEach不会返回东西(forEach一般是直接加工数据)
- 所以,使用map刚好合适,这样的话返回吐出来的数组正好可以为Promise.all所用
- 如下:
async function getAgeFn(arr) {
// 给数组循环赋值
let newArr = arr.map(async (item) => {
item.age = await getAge(item.name) // 年龄赋值等待
return item
})
// Promise接收一个数组
await Promise.all(newArr)
// 执行完毕,再往下走
console.log('最终加工好的数组结果:', arr);
}
getAgeFn(arr)
完整代码
赋值粘贴即可演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>循环异步请求</title>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.0/axios.js"></script>
</head>
<body>
<script>
let arr = [
{
name: '孙悟空',
id: '111',
age: null
},
{
name: '猪八戒',
id: '222',
age: null
},
{
name: '沙和尚',
id: '333',
age: null
},
{
name: '唐僧',
id: '444',
age: null
},
{
name: '白龙马',
id: '555',
age: null
},
]
function getAge(name) {
return new Promise((resolve, reject) => {
axios.get(`http://ashuai.work/api/getAge?name=${name}`).then((res) => {
let age = res.data.data.age
console.log(`获取 ${name} 的年龄为: ${age}`);
resolve(age)
}).catch((err) => {
reject(err)
})
})
}
async function getAgeFn(arr) {
// 给数组循环赋值
let newArr = arr.map(async (item) => {
item.age = await getAge(item.name)
return item
})
// Promise接收一个数组
await Promise.all(newArr)
// 执行完毕,再往下走
console.log('最终加工好的数组结果:', arr);
}
getAgeFn(arr)
</script>
</body>
</html>
效果图
笔者还有一篇Promise的文章可以瞅瞅:
- Promise.all和promise.race的应用场景举例:
- https://segmentfault.com/a/1190000040554192
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。