【发布时间】:2023-03-26 01:05:01
【问题描述】:
我需要递归调用 API 来遍历子条目,并在继续之前返回过滤后的结果。我最初将结果放在一个数组中,然后执行.forEach,如果找到匹配项,我需要递归这样做;但是,由于this question 的答案中描述的问题,这不起作用。因此,我尝试修改该问题的答案,但它仍然没有等待。
const getDatabases = async (blockId) => {
let databases = [];
let childDatabases = [];
const children = await getChildren(blockId);
Promise.all(children.results
.filter( (child) => {
return (['child_database', 'database'].includes(child.type)
|| child.has_children === true);
})
.map( async (child) => {
if (['child_database', 'database'].includes(child.type)) {
return { id: child.id, title: child.child_database.title };
} else {
console.log(`Waiting on getDatabases for ${child.id}`); // 1
childDatabases = await getDatabases(child.id);
return false;
}
})
)
.then((childDbs) => {
console.log(`Got childDbs`); // 3, 4
databases =
[...databases, ...childDatabases].filter(dbId => dbId !== false);
return databases;
})
.catch((err) => console.log(err));
}
app.get('/api', async (req, res) => {
const dashboardPage = await getDashboardPage();
const databases = await getDatabases(dashboardPage);
console.log('No longer awaiting getDatabases'); // 2
...
}
所以问题是,为什么 2 发生在 3 和 4 之前,而不是在它们之后? 2 之前的 const databases = await getDatabases(dashboardPage); 不应该等待 1 之后通过 childDatabases = await getDatabases(child.id); 的所有递归调用吗?
【问题讨论】:
-
回答你的问题,你试过
await Promise.all(code)吗?因为Promise.all()本身就是一个Promise,或者Promise.all返回一个Promise。 -
啊哈!是的,这是有道理的。所以
Promise.all在里面等待async/await,在它到达.then之前,但是父函数只是触发了这些承诺并且什么也不返回,因为没有人告诉它等待它们. -
是的,没错。现在你可以自己回答你的问题,因为我今天没有太多时间,所以我不会发布答案。写一个答案也比阅读一个答案更能提高你对 async-await 的了解。我会给你a reference to Promise.all。
-
除了缺少
await,您的函数还缺少return语句;变量databases和childDatabases的使用很奇怪。childDatabases在每次map迭代中都会被覆盖,从而丢弃许多递归调用的结果。并且永远不会使用您的承诺数组中的childDbs结果值! -
@Bergi,是的——这两个都是我在修复这个问题之前没有发现的错误:) 我使用 StackOverflow 的程度不足以对礼仪充满信心。如果有意义,我可以返回并编辑帖子,以免出现那些不相关的错误。
标签: javascript node.js async-await es6-promise