Javascript 遍历数组并等待处理承诺
我正在创建一个todo应用程序,我希望每个todo列表都有一个唯一的名称。每个用户都有一组待办事项列表。创建新列表的传入POST请求已附加用户对象,因此我可以使用Javascript 遍历数组并等待处理承诺,javascript,arrays,node.js,Javascript,Arrays,Node.js,我正在创建一个todo应用程序,我希望每个todo列表都有一个唯一的名称。每个用户都有一组待办事项列表。创建新列表的传入POST请求已附加用户对象,因此我可以使用const userLists=req.user.list获取数组。这(如果我将其记录在控制台日志中)是每个列表\u id 我正在尝试循环遍历这些对象,以获取list对象并测试名称,以查看它是否等于req.body.name,以确保唯一性 我希望保持函数异步,因为我下面有更多的逻辑,并且不希望嵌套太多回调函数 我试过了 exports.
const userLists=req.user.list
获取数组。这(如果我将其记录在控制台日志中)是每个列表\u id
我正在尝试循环遍历这些对象,以获取list对象并测试名称,以查看它是否等于req.body.name
,以确保唯一性
我希望保持函数异步
,因为我下面有更多的逻辑,并且不希望嵌套太多回调函数
我试过了
exports.createList = async (req, res) => {
const usersLists = req.user.lists;
let proms = [];
let found = false;
userLists.map(list => {
const listObj = List.findOne({_id : list});
if(listObj.name === req.body.name)
found = true
})
(other code below to create list)
还试图等待List.findOne()
但是我不能异步
映射
我相信代码正在运行,因此found
永远都不是真的
然后我在网上看到了一些使用了Promise.all()
的东西,所以我尝试了以下方法:
let proms = []
usersLists.map(listId => {
proms.push(List.findOne({_id: listId}, "name").exec());
});
await Promise.all(proms.map(p => {
if(p.name == req.body.name)
found = true;
}))
但是下面的代码仍然在运行,并且创建了列表。如果iconsole.log(proms)
则它由一个[objectpromise]数组组成
它对我来说还是相当新的,我所要做的就是循环遍历列表id的数组,获取列表对象并测试是否有任何列表名称与我想要创建的新列表的名称相等(并返回一个错误)
任何帮助都将不胜感激。谢谢让我在这里把问题分解一下
let proms = []
usersLists.map(listId => {
proms.push(List.findOne({_id: listId}, "name").exec());
});
await Promise.all(proms.map(p => {
if(p.name == req.body.name)
found = true;
}))
首先,
let proms = []
usersLists.map(
将返回一个新数组,这样您就不需要使用let proms=[]
并将其推送到它。
您还可以在map回调中使用async/await
。
你能做的是
const promises = usersLists.map(async listId => {
const prom = await List.findOne({_id: listId}, "name").exec();
if(p.name == req.body.name) // I put this here so we don't have to make another loop
found = true;
});
映射循环完成后,承诺
将是一个承诺数组。因此,为了让javascript等待所有这些承诺,您现在将使用Promise.all(promises)
。
要做到这一点,以下是方法
await Promise.all(promises);
给你,最后的输出
const promises = usersLists.map(async listId => {
const prom = await List.findOne({_id: listId}, "name").exec();
if(p.name == req.body.name)
found = true;
});
await Promise.all(promises);
让我在这里把问题分解一下
let proms = []
usersLists.map(listId => {
proms.push(List.findOne({_id: listId}, "name").exec());
});
await Promise.all(proms.map(p => {
if(p.name == req.body.name)
found = true;
}))
首先,
let proms = []
usersLists.map(
将返回一个新数组,这样您就不需要使用let proms=[]
并将其推送到它。
您还可以在map回调中使用async/await
。
你能做的是
const promises = usersLists.map(async listId => {
const prom = await List.findOne({_id: listId}, "name").exec();
if(p.name == req.body.name) // I put this here so we don't have to make another loop
found = true;
});
映射循环完成后,承诺
将是一个承诺数组。因此,为了让javascript等待所有这些承诺,您现在将使用Promise.all(promises)
。
要做到这一点,以下是方法
await Promise.all(promises);
给你,最后的输出
const promises = usersLists.map(async listId => {
const prom = await List.findOne({_id: listId}, "name").exec();
if(p.name == req.body.name)
found = true;
});
await Promise.all(promises);
Promise.all
接受包含承诺的数组,并在所有承诺完成后解析。请阅读
假设上述代码在异步
函数中执行
let found = false;
let proms = usersLists.map(listId => List.findOne({
_id: listId
}, "name").exec());
let userDetails = await Promise.all(proms);
for (let index = 0; index < userDetails.length; index++) {
const user = userDetails[index]
if (user.name === req.body.name) {
found = true
}
}
let found=false;
让proms=usersLists.map(listId=>List.findOne({
_id:listId
},“name”).exec();
let userDetails=等待承诺。全部(proms);
for(让index=0;index
承诺。所有
接受包含承诺的数组,并在所有承诺完成后解析。请阅读
假设上述代码在异步
函数中执行
let found = false;
let proms = usersLists.map(listId => List.findOne({
_id: listId
}, "name").exec());
let userDetails = await Promise.all(proms);
for (let index = 0; index < userDetails.length; index++) {
const user = userDetails[index]
if (user.name === req.body.name) {
found = true
}
}
let found=false;
让proms=usersLists.map(listId=>List.findOne({
_id:listId
},“name”).exec();
let userDetails=等待承诺。全部(proms);
for(让index=0;index
如我所见,试试这个
let found = false
// proms:users all message in List model
let proms = await Promise.all(
// usersLists: user id message ['', '']
usersLists.map(async listId => {
// List: user model, listObj {_id: '', name: ''}
const listObj = await List.findOne({_id : listId});
if(listObj.name == req.body.name){
found = true
}
return listObj
});
)
// other code
如我所见,试试这个
let found = false
// proms:users all message in List model
let proms = await Promise.all(
// usersLists: user id message ['', '']
usersLists.map(async listId => {
// List: user model, listObj {_id: '', name: ''}
const listObj = await List.findOne({_id : listId});
if(listObj.name == req.body.name){
found = true
}
return listObj
});
)
// other code
所有的响应,即使它们是有效的,也倾向于在异步操作中更改外部变量,这显然是不应该做的,永远也不应该 理论上,它应该简化为(未经测试):
const promises=usersLists.map(listId=>List.findOne({u id:listId},“name”);
const isFound=等待承诺。全部(承诺)。然后(arr=>{
//检查您的阵列
//返回真或假
});
console.log(“结果…”,isFound);
顺便说一下。。。您始终可以查询mongo,而无需执行大量findOne。通常,您可以在一次调用中完成,或者至少在较少的调用中对其进行分组。所有响应,即使它们是有效的,也会在异步操作中更改外部变量,这显然是您不应该做的,永远不会 理论上,它应该简化为(未经测试):
const promises=usersLists.map(listId=>List.findOne({u id:listId},“name”);
const isFound=等待承诺。全部(承诺)。然后(arr=>{
//检查您的阵列
//返回真或假
});
console.log(“结果…”,isFound);
顺便说一下。。。您始终可以查询mongo,而无需执行大量findOne。通常,您可以在一次呼叫中完成,或者至少在较少的呼叫中进行分组。它应该是
const listObjs=wait Promise.all(proms)代码>。然后,您可以循环浏览listObjs
。太棒了。非常感谢。它应该是const listObjs=wait Promise.all(proms)代码>。然后,您可以循环浏览listObjs
。太棒了。非常感谢。谢谢,很好用。如果我们在寻找时等待,我一定会错过一件事。为什么我们还需要Promise.all()
另外。。。执行“find=true”是一种非常糟糕的做法,它容易出错,而且对比赛条件非常友好。all返回一个已完成响应的数组,您只需在该数组上使用“then”并使用“some”之类的函数来查找所需的内容。声明在承诺中更改的外部变量是需要避免的,因为usersLists.map(
不同步迭代。每次迭代都将并发处理。await
仅在使用的async
函数中起作用,外部函数不会等待内部函数的await
s。谢谢各位,我将尝试删除该函数