Как сделать forEach l oop синхронным - PullRequest
3 голосов
/ 10 июля 2020

У меня здесь асинхронная проблема. 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 });
    }
}

Ответы [ 4 ]

2 голосов
/ 10 июля 2020

Используйте вместо этого for...of до l oop над элементами массива, и вы можете использовать await.

for(const field of Object.keys(reqBody)){
   //Code using await
}
1 голос
/ 10 июля 2020

с использованием map вместо forEach для получения обещаний 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 голос
/ 10 июля 2020

Мне не нравится синтаксис ожидания в функции asyn c l oop. Но если бы я сохранил существующую структуру карты, я бы, вероятно, добавил бы массив вне нее для хранения пустых обещаний. Pu sh обещание в этот массив каждый раз, когда вы l oop, а затем разрешайте его после вашего ожидания и вашего нажатия ошибки. Затем поместите await Promise.all в этот массив между ключом вашего объекта l oop и установкой ответа.

0 голосов
/ 10 июля 2020

Намного проще использовать простой for l oop на Object.keys(reqBody) при работе с asyn c вещами.

let keys =  Object.keys(reqBody)
for(let i in keys){
   ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...