如何使forEach循环同步



这里有一个异步问题。当res.json({ errors });返回时,forEach仍在运行,因此不会拾取所有错误。我该如何处理?

router.post('/new/user', async function (req, res, next) {
const validateEmail = async (email) => {
var re = /^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/;
return re.test(email);
};

const reqBody = { email, password };

let errors = {};
Object.keys(reqBody).forEach(async (field) => {
if (field === 'email' && validateEmail(await reqBody[field])) {
errors = { ...errors, [field]: 'Not a valid Email' };
}
console.log(3);

if (field === 'password' && password !== '' && password < 4) {
errors = { ...errors, [field]: 'Password too short' };
}
});

if (Object.keys(errors).length > 0) {
res.json({ errors });
}
}

使用for...of在数组元素上循环,您可以使用await

for(const field of Object.keys(reqBody)){
//Code using await
}

使用map而不是forEach来获得PromiseObject.keys(reqBody).map(async (field) => {...},然后使用Promise。allSettled等待所有承诺得到解决或拒绝,您可以捕捉该错误以记录

router.post('/new/user', async function (req, res, next) {
const validateEmail = async (email) => {
var re = /^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/;
return re.test(email);
};

const reqBody = { email, password };

try{
const promises =  Object.keys(reqBody).map(async (field) => {
if (field === 'email' && validateEmail(await reqBody[field])) {
Promise.reject({[field]: 'Not a valid Email'})
}
console.log(3);

if (field === 'password' && password !== '' && password < 4) {
Promise.reject({[field]: 'Password too short'})
}
});
// List of resolved and rejected promises
const results = await Promise. allSettled(promises)
const errors = results.filter(result => result.status === "rejected")
if (Object.keys(results).length > 0) {
res.json({ errors });
}
}catch(error){
res.json({ error });
}
}

我不喜欢在异步循环函数中等待的语法。但如果我要保留现有的地图结构,我可能会在它的外部添加一个数组来保存空白的承诺。每次循环时将promise推入该数组,然后在等待和推送错误后解决它。然后在对象键循环和设置响应之间的数组上放置await Promise.all。

在处理异步内容时,只在Object.keys(reqBody)上使用普通的for循环要容易得多。

let keys =  Object.keys(reqBody)
for(let i in keys){
...
}

最新更新