所以我有一个带有嵌套数组(sources.feed)的数组(sources),sources应该串联运行(一个接一个),sources.feed应该并行运行。
我已经实现了同时运行它们:
for (const source of sources) {
for (const feed of source.feeds) {
await ProcessService.getData(feed, source)
}
}
console.log('Done processing.') //Triggers at the end (as expected)
这是我几次尝试的最后一次:
for (const source of sources) {
await Promise.all(source.feeds.map(async (feed) => {
await ProcessService.getData(feed, source)
}))
}
console.log('Done processing.') //Triggers before it is done
为清楚起见已更新(只能调用ProcessService.getData())
getData: async function(data, source) {
return new Promise(async (resolve, reject) => {
try {
...
resolve()
} catch(e) {
reject(e)
}
})
}
答案 0 :(得分:4)
在您的第一个代码块中(您说的有效,但是连续),您正在调用ProcessService.getData
,而在第二个代码块中,您正在调用RSSService.getRssAsync
。
如果我假设您打算使用ProcessService.getData
并且它返回一个promise(我认为必须这样做,那么您说您的第一个代码块可以按预期工作),然后使提要并行类似于 的第二个代码块,但不必太复杂:
for (const source of sources) {
await Promise.all(source.feeds.map(feed => ProcessService.getData(feed, source)));
}
console.log('Done processing.');
由于ProcessService.getData
返回了一个promise,而我们想要的Promise.all
是一个promise数组,因此我们不进行回调async
,我们只使用promise {{1 }}给了我们。
依次遍历各个源,获取(并行)第一个源的所有提要,然后获取(并行)下一个源的所有提要,等等。
实时示例:
ProcessService.getData
(async () => {
const ProcessService = {
getData(data, source) {
return new Promise((resolve, reject) => {
setTimeout(() => {
try {
console.log(`Done with feed ${source.name} ${data}`);
resolve(/*...should have data here...*/)
} catch(e) {
reject(e)
}
}, Math.random() * 500);
});
}
}
const sources = [
{name: "Source 1", feeds: ["11", "12", "13"]},
{name: "Source 2", feeds: ["21", "22", "23"]},
{name: "Source 3", feeds: ["31", "32", "33"]},
{name: "Source 4", feeds: ["41", "42", "43"]}
];
for (const source of sources) {
console.log(`Processing ${source.name}`);
await Promise.all(source.feeds.map(feed => ProcessService.getData(feed, source)));
}
console.log('Done processing.');
})().catch(e => {
console.error(`Error: ${e.message}`);
});
如果您确实需要使用.as-console-wrapper {
max-height: 100% !important;
}
,则它似乎不会返回承诺,因为即使这样做,您的代码也可以按预期工作(即使可能更简单)。要将回调API转换为Promise API,请参见this question's answers。
您的RSSService.getRssAsync
函数有两个问题:
getData
函数。当您要在现有承诺中使用async
时,可以使用async
功能。如果您要创建新的承诺,则几乎不需要使用await
函数。async
的函数(承诺执行器函数)应该永远不为new Promise
。async
。如果您真的想用值resolve()
(有一些有限的用例)履行承诺,那没关系,但是如果函数被称为undefined
,它实际上应该返回数据,而不是{{ 1}}。所以:
getData
还请注意,您可以使用方法语法(这似乎在对象初始化器中):
undefined
答案 1 :(得分:1)
您可以使用Promise.all
完成此操作。
等待每个系列:
for (const source of sources) {
const promises = [];
for (const feed of source.feeds) {
promises.push(ProcessService.getData(feed, source));
}
// Wait for the series to finish before continuing
await Promise.all(promises);
}
console.log('Done processing.');
最后等待所有嵌套项目:
const promises = [];
for (const source of sources) {
for (const feed of source.feeds) {
promises.push(ProcessService.getData(feed, source));
}
}
// Wait for all of them at the end (instead of each series)
await Promise.all(promises);
console.log('Done processing.');