[Vue]8. 循环里带有异步的多种写法分析

1.预备工作:

首先定义getData()函数,请求后台的数据(随机卡1~4秒后返回),这个request是axios封装,返回一个Promise变量

由于有axios,这个函数显然是异步的,其实也不用管,只要知道这个是异步请求函数就行了

import request from '@/utils/request'
export function getData(x) {
    
    const data = {
       x:x
    }
    return request({
      url: '/getData',
      method: 'post',
      data: data,
    })
}

然后我们的xxx.vue是这样的,点击按钮触发f1(),逻辑容易理解

<template>
  <div class="test">
      <el-button  @click="f1()">获取数据</el-button>
  </div>
</template>

<script>
import {getData} from '@/api/testData' //引入外部的getData函数,灵活处理

export default{
    data(){
        return {
            token:getToken(),
            Data1:{}
        }
    }
    methods:{
       f1(){
         //循环多次调用getData(x)
       }      
    }
}

 

正式开始,我们循环里调用getData()

 

2.1第一种写法,第一直觉写法

f1(){
//方法1
  var dd=[]
  for(let i=0;i<5;i++){
      var res=getData(i)
      let res1=JSON.stringify(res.data.ans)//对象转为json
      console.log("res:"+res1)
      dd.push(res1)
  }
  console.log("dd"+dd)
}

输出:

输出循环里并没有得到数据,原因是getData(i)是异步请求,相当于走分叉了,getData()没处理完就console.log输出了

 

2.2第二种写法   使得循环里输出有数据

由于我们的getData异步返回的是Promise变量,可以加then确保访问后才执行.then后的逻辑

f1(){
//方法2
  var dd=[]
  for(let i=0;i<5;i++){
      getData(i).then((res)=>{
        let res1=JSON.stringify(res.data.ans)//对象转为json
        dd.push(res1)
        console.log("ddli:"+dd)
      })
  }
  console.log("ddwai:"+dd)
}

输出:

分析:

里层的dd有数据了,乱序是因为返回的时间不同,先返回的先push进去了

我们外层的dd没有数据那是因为输出语句比getData()的循环先执行了

 

2.3 第三种写法   外层输出也有数据,也就是说等整个循环结束后才往下走

async f1(){
       var dd=[]
       ! await function f2(){
            return new Promise(resolve=>{

                    var cnt=0;
                    for(let i=0;i<5;i++){
                        getData(i).then((res)=>{
                            let res1=JSON.stringify(res.data.ans)//对象转为str
                            dd.push(res1)
                            console.log("ddli:"+dd)
                            cnt++;
                            if(cnt==5)resolve()
                        })
                    }
                    
             })
       }()
       console.log("ddwai:"+dd)
}

输出:

分析:首先我们使用async 与await

async 函数(){}  :声明函数里含有异步

await  表达式    等待表达式/包括函数,完成后才往下走,这里我们配合Promise来使用

那么我们的写法就是

 await 函数()
 { 
    返回一个Promise对象 
    return new Promise(
        resolve=>{
            异步函数().then(
                (异步函数返回的结果)=>{
                    if(满足条件){
                        resolve()结束Promise
                    }
                }
            )
            
        }
    )
 }

!function f2(){}()
等价于  
function f2(){}
f2()

在Promise对象里 当if(满足条件){ resolve(); }来结束Promise 往下走

在这里我们的满足条件就是5个getData()全部完成,因此我们加一个计数器cnt来记录

 

 

2.4第四种写法 外层输出有数据,且返回依次按顺序执行(使用递归)

async f1(){
       var dd=[]
       ! await function f2(){
            return new Promise(resolve=>{

                var x=0;
                dfs(x)
                function dfs(x){ //递归
                    getData(x).then((res)=>{
                        let res1=JSON.stringify(res.data.ans)//对象转为json
                        dd.push(res1)
                        console.log("ddli:"+dd)
                        x++;
                        if(x<5){
                            dfs(x)
                        }else{
                            resolve()//递归完成,返回Promise.resolve
                        }
                    })
                }
                    
             })
       }()
       await console.log("ddwai:"+dd)
}

输出:

不仅会按顺序依次返回(解决有依赖的情况),而且外层也有值了

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值