循环中使用async/await

博客讨论了在JavaScript中处理嵌套循环时遇到的异步问题,以及如何通过Promise.all和for循环中的async/await解决。通过示例展示了如何正确地并行处理数组中的任务,避免错误的输出顺序,从而实现预期的数组操作。解决方案包括使用Promise.all对二次循环中的任务进行批量处理,以及在for循环中直接使用async/await来控制流程。
摘要由CSDN通过智能技术生成

此需求在于二次循环中需要使用async/await,按照每次嵌套循环的时候,进行async,则会给出错误的输出,如下所示

let list = [
    {
        name: "a",
        age: 1
    },
    {
        name: "b",
        age: 2
    }, {
        name: "c",
        age: 3
    }
];
let list2 = [
    {
        name: "a1",
        age: 1
    },
    {
        name: "b1",
        age: 2
    }, {
        name: "c1",
        age: 3
    }
];

function test() {
    list.forEach(async item => {
        let arr = [];
        await list2.forEach(async item => {
            let info2 = await asyncItem2(item);
            console.log("info2", info2)
            arr.push(info2)
        })
        console.log("--------arr", arr)
        let info = await asyncItem(item);
        console.log("test", info)

    })
}


async function asyncItem(item) {
    item.index = item.age;
    console.log("asyncItem", item.age)
    return Promise.resolve(item);
}


async function asyncItem2(item) {
    item.index = item.age;
    console.log("asyncItem2", item.age)
    return Promise.resolve(item);
}

//执行函数
test()

//以上,你将得到如下输出
asyncItem2 1
asyncItem2 2
asyncItem2 3
asyncItem2 1
asyncItem2 2
asyncItem2 3
asyncItem2 1
asyncItem2 2
asyncItem2 3
--------arr []
asyncItem { name: 'a', age: 1 }
--------arr []
asyncItem { name: 'b', age: 2 }
--------arr []
asyncItem { name: 'c', age: 3 }
info2 { name: 'a1', age: 1, index: 1 }
info2 { name: 'b1', age: 2, index: 2 }
info2 { name: 'c1', age: 3, index: 3 }
info2 { name: 'a1', age: 1, index: 1 }
info2 { name: 'b1', age: 2, index: 2 }
info2 { name: 'c1', age: 3, index: 3 }
info2 { name: 'a1', age: 1, index: 1 }
info2 { name: 'b1', age: 2, index: 2 }
info2 { name: 'c1', age: 3, index: 3 }
test { name: 'a', age: 1 }
test { name: 'b', age: 2 }
test { name: 'c', age: 3 }


上述的67、69、71行很明显不是我们想要的输出,我们想要的是输出一个新的数组

解决方案:

1.利用Promise.all

可以将二次循环中的async封装成promise函数,同时利用Promise.all进行统一执行;

let list = [
    {
        name: "a",
        age: 1
    },
    {
        name: "b",
        age: 2
    }, {
        name: "c",
        age: 3
    }
];
let list2 = [
    {
        name: "a1",
        age: 1
    },
    {
        name: "b1",
        age: 2
    }, {
        name: "c1",
        age: 3
    }
];

function test(){
    list.forEach(async item=>{
        let arr = await promiseAllList();
        console.log("---arr",arr)
        let info = await asyncItem(arr);
        console.log("test",info)

    })
}


async function promiseAllList() {
    let arr = [];
    list2.forEach(item => {
        let info2 = promiseItem(item);
        arr.push(info2)
    })
    console.log("-----promiseAllList", arr)
    let result = await Promise.all(arr);
    console.log("result", result)
    return result;
}

async function promiseItem(item) {
    let info2 = await asyncItem2(item);
    console.log("info2", info2)
    return Promise.resolve(info2);
}

async function asyncItem(item) {
    console.log("asyncItem", item)
    return Promise.resolve(item);
}


async function asyncItem2(item) {
    item.index = item.age;
    console.log("asyncItem2", item.age)
    return Promise.resolve(item);
}

//执行函数
test()


//函数输出如下
asyncItem2 1
asyncItem2 2
asyncItem2 3
-----promiseAllList [ Promise { <pending> }, Promise { <pending> }, Promise { <pending> } ]
asyncItem2 1
asyncItem2 2
asyncItem2 3
-----promiseAllList [ Promise { <pending> }, Promise { <pending> }, Promise { <pending> } ]
asyncItem2 1
asyncItem2 2
asyncItem2 3
-----promiseAllList [ Promise { <pending> }, Promise { <pending> }, Promise { <pending> } ]
info2 { name: 'a1', age: 1, index: 1 }
info2 { name: 'b1', age: 2, index: 2 }
info2 { name: 'c1', age: 3, index: 3 }
info2 { name: 'a1', age: 1, index: 1 }
info2 { name: 'b1', age: 2, index: 2 }
info2 { name: 'c1', age: 3, index: 3 }
info2 { name: 'a1', age: 1, index: 1 }
info2 { name: 'b1', age: 2, index: 2 }
info2 { name: 'c1', age: 3, index: 3 }
result [
  { name: 'a1', age: 1, index: 1 },
  { name: 'b1', age: 2, index: 2 },
  { name: 'c1', age: 3, index: 3 }
]
result [
  { name: 'a1', age: 1, index: 1 },
  { name: 'b1', age: 2, index: 2 },
  { name: 'c1', age: 3, index: 3 }
]
result [
  { name: 'a1', age: 1, index: 1 },
  { name: 'b1', age: 2, index: 2 },
  { name: 'c1', age: 3, index: 3 }
]
---arr [
  { name: 'a1', age: 1, index: 1 },
  { name: 'b1', age: 2, index: 2 },
  { name: 'c1', age: 3, index: 3 }
]
asyncItem [
  { name: 'a1', age: 1, index: 1 },
  { name: 'b1', age: 2, index: 2 },
  { name: 'c1', age: 3, index: 3 }
]
---arr [
  { name: 'a1', age: 1, index: 1 },
  { name: 'b1', age: 2, index: 2 },
  { name: 'c1', age: 3, index: 3 }
]
asyncItem [
  { name: 'a1', age: 1, index: 1 },
  { name: 'b1', age: 2, index: 2 },
  { name: 'c1', age: 3, index: 3 }
]
---arr [
  { name: 'a1', age: 1, index: 1 },
  { name: 'b1', age: 2, index: 2 },
  { name: 'c1', age: 3, index: 3 }
]
asyncItem [
  { name: 'a1', age: 1, index: 1 },
  { name: 'b1', age: 2, index: 2 },
  { name: 'c1', age: 3, index: 3 }
]
test [
  { name: 'a1', age: 1, index: 1 },
  { name: 'b1', age: 2, index: 2 },
  { name: 'c1', age: 3, index: 3 }
]
test [
  { name: 'a1', age: 1, index: 1 },
  { name: 'b1', age: 2, index: 2 },
  { name: 'c1', age: 3, index: 3 }
]
test [
  { name: 'a1', age: 1, index: 1 },
  { name: 'b1', age: 2, index: 2 },
  { name: 'c1', age: 3, index: 3 }
]

2.for循环中调用async/await

function getData(n){
    return  new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(n+1)//原来的数据上+1
        },1000)
    })
}

let data = [0,1,2,3,4];

async function subData(){//提交数据保存
    for(let i = 0;i<data.length;i++){
        const res = await getData(data[i])
        console.log(res)
    } //改变数据

    console.log('sub')//提交数据
}

subData()

// 1
// 2
// 3
// 4
// 5
// subData: 5.009s
// sub

3.递归函数

function getData(n){//通过该接口改变数据
    // console.log('n',n)
    return  new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(n+1)//原来的数据上+1
        },1000)
    })
}

let data = [0,1,2,3,4]

async function digui(index,arr){
    if(index<data.length){
        let res = await getData(data[index])
        console.log(res)
        arr.push(res)
        await digui(index+1,arr)
    }

    return arr
}

async function subData1(){
    const newList = await digui(0,[])
    // console.log(newList)
    console.timeEnd("subData1")
    console.log('sub')
}

subData1()
console.time("subData1")

//1
// 2
// 3
// 4
// 5
// subData1: 5.010s
// sub

4.Promise.map

这个方法将使用一些插件依赖
bluebird
https://www.npmjs.com/package/bluebird

例子

function getData(n){
    return  new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve(n+1)//原来的数据上+1
        },1000)
    })
}

let data = [0,1,2,3,4];



async function subData2(){
    await Bluebird.map(data,async item => {
         let res = await getData(item);
         console.log(res)
        return null;
    }, {concurrency: 10})
    console.timeEnd("subData1")
    console.log('sub')
}

subData2()
console.time("subData1")


// 1
// 2
// 3
// 4
// 5
// subData1: 1.016s
// sub

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乾复道

与君共勉

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值