不知道该术语是否正确,但是我有一个对象数组,其中也有其他数组。我需要检查所有这些项目。如果操作不是异步的,则看起来像这样:
myArray.forEach(x => {
x.otherArray.forEach(y => {
doSomething(y)
})
})
尽管doSomething
函数是async
,但不幸的是,我很清楚,在这些迭代过程中,我不能简单地通过几个异步操作并等待使其工作。
通常,当我需要在迭代过程中做出承诺时,请执行以下操作:
await myArray.reduce((p, item) => {
return p.then(() => {
return doAsyncSomething(item)
})
}, Promise.resolve())
但是因为我一次要进行两次迭代,所以这变得有点复杂,那么我该怎么做呢?
我目前有这样的东西,但这似乎不是正确的方法:
await myArray.reduce((p, item) => {
return item.someArray.reduce((promise, it, index) => {
return promise.then(() => {
return doAsyncSomething()
})
}, Promise.resolve())
}, Promise.resolve())
我知道我可以只通过两个forEach
将对象组织成一个数组,然后将reduce
与其中的doSomething
一起使用,但是我怀疑这是最有效或最优雅的方法完成的方式。那我该怎么办呢?
答案 0 :(得分:2)
尝试一下:
let objArray = [ {otherArray: [1,2]}, {otherArray: [3,4]}, {otherArray: [5,6]} ];
function doAsyncSomething(item) {
return Promise.resolve(item);
}
async function doit() {
let s = 0;
for(const x of objArray)
for(const y of x.otherArray)
s+= await doAsyncSomething(y);
return s;
}
doit().then(v => {
console.log(v);
});
或尝试像这样的递归调用:
let objArray = [ {otherArray: [1,2]}, {otherArray: [3,4]}, {otherArray: [5,6]} ];
let index = 0;
let subIndex = 0;
function doAsyncSomething(item) {
return new Promise(resolve => {
console.log("proc item", item);
resolve(item);
});
}
async function doit() {
return await doAsyncSomething(objArray[index].otherArray[subIndex]);
}
function go() {
doit().then(v => {
console.log(v);
subIndex++;
if (subIndex >= objArray[index].otherArray.length) {
subIndex = 0;
index++;
}
if (index < objArray.length)
go();
});
}
答案 1 :(得分:0)
减少时将promise传递到内部循环中
await myArray.reduce((p, item) =>
item.someArray.reduce((p, it, index) =>
p.then(() => doAsyncSomething(it)),
p // <<<
),
Promise.resolve()
)
或者我更喜欢:
for(const { someArray } of myArray) {
for(const it of someArray) {
await doSomethingAsync(it);
}
}
如果要并行运行任务:
await Promise.all(
myArray.flatMap(item => item.someArray.map(doSomethingAsnyc))
);
答案 2 :(得分:0)
假设您希望所有操作并行进行,则可以使用Promise.all()
:
async function () { // I assume you already have this
// ...
let asyncOps = [];
myArray.forEach(x => {
x.otherArray.forEach(y => {
asyncOps.push(doSomething(y));
})
})
await Promise.all(asyncOps);
}
function doSomething (x) {
return new Promise((ok,fail) =>
setTimeout(() => {
console.log(x);
ok();
},10));
}
let foo = [[1,2,3,4],[5,6,7,8]];
async function test() {
let asyncOps = [];
foo.forEach(x =>
x.forEach(y =>
asyncOps.push(doSomething(y))));
await Promise.all(asyncOps);
}
test();
如果要顺序执行异步操作,则更加简单:
async function () { // I assume you already have this
// ...
for (let i=0; i<myArray.length; i++) {
let x = myArray[i];
for (let j=0; j<x.length; j++) {
let y = x[j];
await doSomething(y);
}
}
}