带有多个猫鼬查找的foreach循环后的javascript承诺
Posted
技术标签:
【中文标题】带有多个猫鼬查找的foreach循环后的javascript承诺【英文标题】:javascript promise after foreach loop with multiple mongoose find 【发布时间】:2019-05-22 14:59:04 【问题描述】:我正在尝试使用一些 db 调用进行循环,一旦它们全部完成,就会发送结果。 - 使用一个承诺,但如果我在回调之后有我的承诺,它就不起作用。
let notuser = [];
let promise = new Promise((resolve, reject) =>
users.forEach((x) =>
User.find(
/* query here */
, function(err, results)
if(err) throw err
if(results.length)
notuser.push(x);
/* resolve(notuser) works here - but were not done yet*/
)
);
resolve(notuser); /*not giving me the array */
).then((notuser) =>
return res.json(notuser)
)
我该如何处理?
【问题讨论】:
映射查询承诺数组并使用Promise.all()
【参考方案1】:
下面是一个名为findManyUsers
的函数,它可以满足您的需求。 Mongo find 会返回一个 Promise 给你,所以只需在循环中收集这些 Promise 并与 Promise.all()
一起运行它们。所以你可以看到它的实际效果,我添加了一个模拟 User 类,它带有一个返回 promise 的 find 方法......
// User class pretends to be the mongo user. The find() method
// returns a promise to 'find" a user with a given id
class User
static find(id)
return new Promise(r =>
setTimeout(() => r( id: `user-$id` ), 500);
);
// return a promise to find all of the users with the given ids
async function findManyUsers(ids)
let promises = ids.map(id => User.find(id));
return Promise.all(promises);
findManyUsers(['A', 'B', 'C']).then(result => console.log(result));
【讨论】:
【参考方案2】:我建议你看看async,它是一个很棒的库,可以处理这类事情等等,我真的认为你应该习惯于实现它。
我会使用以下方法解决您的问题
const async = require('async')
let notuser = [];
async.forEach(users, (user, callback)=>
User.find(, (err, results) =>
if (err) callback(err)
if(results.length)
notUser.push(x)
callback(null)
)
, (err) =>
err ? throw err : return(notuser)
)
但是,如果您不想使用 3rd 方库,最好使用 promise.all 并等待它完成。
编辑:记得安装async
使用npm
或yarn
类似于yarn add async
的东西——npm install async
【讨论】:
err ? throw err : return(notuser)
在异步回调中真的没有意义
我只是按照他的逻辑,他想在有错误的时候抛出一个错误。我的示例背后的目标是向用户展示 async【参考方案3】:
我使用@danh 解决方案作为在我的场景中进行修复的基础(因此值得称赞),但我认为我的代码可能与其他人相关,希望在没有异步的情况下使用标准猫鼬。我想获取某个状态的报告数量的摘要,并返回每个报告的最后 5 个,并合并为一个响应。
const Report = require('../../models/report');
const Workspace = require('../../models/workspace');
// GET request to return page of items from users report
module.exports = (req, res, next) =>
const workspaceId = req.params.workspaceId || req.workspaceId;
let summary = [];
// returns a mongoose like promise
function addStatusSummary(status)
let totalItems;
let $regex = `^$status$`;
let query =
$and: [ workspace: workspaceId , status: $regex, $options: 'i' ],
;
return Report.find(query)
.countDocuments()
.then((numberOfItems) =>
totalItems = numberOfItems;
return Report.find(query)
.sort( updatedAt: -1 )
.skip(0)
.limit(5);
)
.then((reports) =>
const items = reports.map((r) => r.displayForMember());
summary.push(
status,
items,
totalItems,
);
)
.catch((err) =>
if (!err.statusCode)
err.statusCode = 500;
next(err);
);
Workspace.findById(workspaceId)
.then((workspace) =>
let promises = workspace.custom.statusList.map((status) =>
addStatusSummary(status)
);
return Promise.all(promises);
)
.then(() =>
res.status(200).json(
summary,
);
)
.catch((err) =>
if (!err.statusCode)
err.statusCode = 500;
next(err);
);
;
【讨论】:
以上是关于带有多个猫鼬查找的foreach循环后的javascript承诺的主要内容,如果未能解决你的问题,请参考以下文章