for循环axios问题(pdd面试)

3,538 阅读2分钟

问题背景

  • 经历了一次失败的面试,非常惨痛,所以有了这篇文章。

出题

面试官这样出题的

  • 给你一个userIdList,用户id列表.
  • 只有一个接口,根据userId获取单个用户userInfo信息。
  • 如何渲染出多个用户信息列表userInfoList,没有用户信息列表的接口

做题

  • 实际根本不会有这种场景,但面试官是大牛,来吧。

1、我的思路for循环这个axios

  • 网上找了个接口,根据名字查找年龄
  • https://api.agify.io/?name=lucy
  • ['nice','david','tony']这三个人对应的年龄应该是[19,63,54]
//promiseList:[] 这个是渲染列表项
const nameList = ['nice','david','tony']
for(let i of nameList){
          axios.get(
            `https://api.agify.io/?name=${i}`,
          ).then(res=> {
              this.promiseList.push(res.data.age)
            console.log(400,res.data.age)
          })
        }

当时是这么写的,面试官说有问题,然后我就套了个promise

2、axios嵌套promise

for(let i of nameList){
            new Promise((resolve,reject)=>{
              axios.get(
                `https://api.agify.io/?name=${i}`,
              ).then(res=>{
                this.promiseList.push(resolve(res)) //这里面都是undefind
              },err=>{
                reject(err)
              })
            })
        }

当时面试官也不确定对不对,但我这么写是错误的

3、promise正确写法

for(let i of nameList){
            new Promise((resolve,reject)=>{
              axios.get(
                `https://api.agify.io/?name=${i}`,
              ).then(res=>{
                resolve(res)
              },err=>{
                reject(err)
              })
            }).then(res=>{
              this.promiseList.push(res.data.age) //最终值,但是没有按照nameList列表顺序
            })
        }

4、设想

  • 我估计面试官是想考我promise.all([])用法,按照nameList顺序执行
let fnPromiseList = []
        for(let i of nameList){
          fnPromiseList.push(
            new Promise((resolve,reject)=>{
              axios.get(
                `https://api.agify.io/?name=${i}`,
              ).then(res=>{
                resolve(res)
              },err=>{
                reject(err)
              })
            })
          )
        }
        Promise.all(fnPromiseList).then(res=>{
          for(let i of res){
            this.promiseList.push(i.data.age) //永远是[19,63,54]
          }
        })

5、async await写法

async quest_10() {
        const nameList = ['nice', 'david', 'tony']
        //19 63 54
        console.log('old', [19, 63, 54]) //显示顺序

        for (let i of nameList) {
          let val = await axios.get(
            `https://api.agify.io/?name=${i}`,
          )
          this.promiseList.push(val.data.age) //顺序为[19,63,54]
        }

      },

promise总结

  • Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大-阮一峰es6入门中这样写道。
  • 用法之一,当你要封装一个接口,多处要用到这个接口时,需要将接口的回调函数抛出时,这个时候就可以用到promise
  • 例如:微信支付,多处需要使用这个方法的时候。

封装公用接口

promiseTest(){
    /**
     * resolve成功回调,reject失败回调
     * */
    return new Promise((resolve, reject)=>{
        axios.get(
            `https://api.agify.io/?name=手机`
        ).then(res=>{
            resolve(res)
        }).catch(err=>{
            reject(err)
        })
    })
}

使用

const promiseObj = this.promiseTest()
console.log(74, promiseObj)//这是promise对象
            promiseObj.then(res=>{
                console.log(76, res)
            }).catch(err=>{
                console.log(err)
            })

promise语法升级之async await

封装公用接口

async promiseTest(){
    return await axios.get(
                    `https://api.agify.io/?name=鸡儿`
                )
}

使用跟上面一样