gpt4 book ai didi

node.js - Node.js如何等待子查询结果?

转载 作者:太空宇宙 更新时间:2023-11-04 01:22:21 24 4
gpt4 key购买 nike

我正在将 Graphql 与 MongoDB 结合使用。在解析器中使用了子查询,但在执行子查询时主查询返回数据而不等到子查询完成。我想使用解析器中的子查询参数来操作主查询。

  return  await Articles.find({ Status: 1, isPublish : true  })
.sort({TotalClapCount:-1})
.sort({ViewCount:-1})
.skip( offset )
.limit(limit)
.then( async ( lor ) => { await
lor.forEach(async function(data, key){
data["isBookmark"] =
await ArticleBookmarks
.find({ ArticleID : data["ID"], UserID : ArgsUserID, Status : 1 })
.countDocuments()
.then( (hre) =>{return (hre == 1) ? true : false; });
);
});
return lor;
});

我想在单个查询中显示带有书签的文章列表,但return lor在子查询操作之前执行。异步等待是如何工作的?

最佳答案

您可以像这样使用常规 Promise、常规 for 循环和 async/await 。这里不需要外部库函数,例如 async.series():

let lor = await Articles.find({ Status: 1, isPublish: true})
.sort({TotalClapCount: -1})
.sort({ViewCount: -1})
.skip(offset)
.limit(limit);

for (let data of lor) {
let hre = await ArticleBookmarks.find({
ArticleID: data.ID,
UserID: ArgsUserID,
Status: 1
}).countDocuments();
data.isBookmark = (hre == 1);
}
return lor;

变化:

  1. return wait Articles.find() 没有任何用处,因为它与 return Articles.find() 没有什么不同,因为两者都只是返回一个 promise ,因为它位于 async 函数内部,并且所有 async 函数都会返回一个 Promise。

  2. .forEach() 更改为常规 for 循环,因为 for 循环将暂停 for 函数的执行>等待forEach() 不会暂停循环。

  3. await xxx.forEach() 不会 await 任何内容,因为 .forEach() 没有返回值,并且 仅当您等待 promise 时,await才会做一些有用的事情。

  4. 更改(hre == 1)? true : false; 改为 (hre == 1) 因为 hre == 1 已经是一个 bool 值,所以不需要 ?真:假。就个人而言,如果您知道数据实际上是数字而不是字符串,我可能会使用 (hre === 1) 因为 === 几乎总是比==(没有隐式或意外的类型转换)。

  5. 如果您要使用 await,那么在该函数的其他位置使用它通常会更简单,而不是使用 .then(),因为它导致大多数人认为看起来更顺序的代码看起来更简单。

其他评论:

  1. await 仅应在等待 promise 时使用。这是唯一做一些有用的事情的时间。

  2. new Promise() 包裹在其他 Promise 返回函数上被视为 promise anti-pattern因为这是没有必要的,并且会产生很多编程错误的机会,特别是在错误处理方面。您可以返回并使用已有的 promise ,而无需包装新的 promise 。

  3. async.eachSeries() 没有提供任何使用 async/await 的常规 Promise 排序已经可以做到的功能,除非您尝试在环境中运行没有async/await

  4. 当您希望 await 暂停循环时,请使用常规 for 循环。它不会暂停 .map().forEach() 等数组方法的循环,因为这些迭代方法不支持 Promise。它们不会在回调返回的 Promise 上暂停(当您将回调声明为异步时就会发生这种情况)。

<小时/>

并行查询的另一种可能性

由于循环的一次迭代的处理独立于其他迭代,因此您可以并行运行所有这些数据库查询并使用 Promise.all() 来了解它们何时完成。这有一个缺点,如果数组很大,您将同时向数据库发出大量查询。好处是,如果数据库没有被同时查询的数量淹没,则端到端处理时间可能会更少。您可以按照以下方式执行此操作:

let lor = await Articles.find({ Status: 1, isPublish: true})
.sort({TotalClapCount: -1})
.sort({ViewCount: -1})
.skip(offset)
.limit(limit);

await Promise.all(lor.map(async data => {
let hre = await ArticleBookmarks.find({
ArticleID: data.ID,
UserID: ArgsUserID,
Status: 1
}).countDocuments();
data.isBookmark = (hre == 1);
});
return lor;

关于node.js - Node.js如何等待子查询结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58812476/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com