此需求在于二次循环中需要使用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

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐