如何使 forEach 循环同步

问题描述 投票:0回答:5

我这里有一个异步问题。当

forEach
返回时,
res.json({ errors });
仍在运行,因此不会检测到所有错误。我该如何处理这个问题?

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 });
    }
}
javascript ecmascript-6
5个回答
4
投票

使用

for...of
来循环遍历数组元素,您可以使用
await

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

1
投票

使用map而不是forEach来获取promise

Object.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 });
    }
}

1
投票

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


0
投票

处理异步内容时,在

for
上使用普通的
 Object.keys(reqBody)
循环要容易得多。

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

0
投票

forEach 循环不适用于同步操作。相反,您可以尝试常规的 for 循环,如下所述 -

for(let i=0; i<Object.keys.length; i++){     
    if(i===email){}    
    .    
    .    
    . 
} 

使用这个,它会起作用。

© www.soinside.com 2019 - 2024. All rights reserved.