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