IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Promise.all应用场景之数组循环请求——异步获取所有项对应数据后再往下走

    水冗水孚发表于 2024-01-17 13:52:32
    love 0

    问题描述

    最近遇到一个奇怪的需求,和大家分享一下

    假设后端返回一个数组,数组数据如下:

    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)
            })
        })
    }

    示例:

    • http://ashuai.work/api/getAge?name=孙悟空
    • http://ashuai.work/api/getAge?name=猪八戒
    • 返回:
    {
        "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


沪ICP备19023445号-2号
友情链接