Почему моя асинхронная функция работает правильно только при изменении синтаксиса вызываемых функций? - PullRequest
0 голосов
/ 30 декабря 2018

Я потратил пару часов, пытаясь заставить правильно работать приведенный ниже асинхронный запрос, и после изучения целой пачки асинхронных запросов, mongoose и node.js оказалось, что моя проблема была более или менее синтаксической проблемой(насколько я понимаю).

Может кто-нибудь сказать мне, почему этот код работает, а мой оригинальный код нет?

Рабочий код:

router.get('/usercheck', function(req, res) {
  var usr = Person.findOne({username: req.query.u}, function(err, user){
    if(user != null){
      return user
    }else return null
  })
   var eml = Person.findOne({email: req.query.e}, function(err, user){
     if(user != null) {
       return user
     }else return null
   });
   var resolve = function(e, u){
     if(e === null && u === null) res.sendStatus(200) //Both available
     else if (e === null && u != null) res.sendStatus(409) //"Email free, user taken"
     else if (e != null && u === null) res.sendStatus(403) //"Email taken, user free"
     else if (e!=null && u!=null) res.sendStatus(418) //"Email and user taken"
     else res.sendStatus(500) // Something broke, no idea what
   }
   async function handler() {
       const user = await usr;
       const email = await eml;
       return resolve(email, user);
   }
   handler();
 });

Оригинальный код:

router.get('/usercheck', function(req, res) {
  function usr() {
    Person.findOne({username: req.query.u}, function(err, user){
      if(user != null){
        return user
      }else return null
    })
  }
  function eml(){
    Person.findOne({email: req.query.e}, function(err, user){
      if(user != null) {
        return user
      }else return null
    });
  }
  var resolve = function(e, u){
    if(e === null && u === null) res.sendStatus(200) //Both available
    else if (e === null && u != null) res.sendStatus(409) //"Email free, user taken"
    else if (e != null && u === null) res.sendStatus(403) //"Email taken, user free"
    else if (e!=null && u!=null) res.sendStatus(418) //"Email and user taken"
    else res.sendStatus(500) // Something broke, no idea what
  }
  async function handler() {
      const user = await usr();
      const email = await eml();
      return resolve(email, user);
  }
  handler();
});

Я уверен, что для этого есть логическая причина, но я ее не понимаю.Насколько я понимаю, оператор return в любой версии кода должен быть передан в метод resolv (), который должен его оценить.

Однако, со второй, оригинальной реализацией, ничто не передается для разрешения () вообще, цикл if else завершается неудачно, и отправляется ошибка 500 возврата;Может кто-нибудь помочь мне понять, почему?

Ответы [ 3 ]

0 голосов
/ 30 декабря 2018

Так много проблем ... для начала асинхронные функции переносят возвращаемые значения как обещания, так что то, что вы на самом деле возвращаете в handler (), является неразрешенным обещанием.

, поэтому конвертируйте function(req, res) в асинхронную версию и await handler() или звоните

handler().then(cb)

Вы также должны придерживаться либо обратных вызовов, либо обещаний в своих моделях мангустов.Если вы пропустите обратный вызов, то возвращаемый результат вызова Model.find/delete/insert() обычно является обещанием.

Я бы предложил рефакторинг кода в нечто вроде.

router.get('/usercheck', async function(req, res) {
  const { u:username, e:email } = req.query;
  try {
    const { username:u, email:e } = await Person.findOne({ username, email });
    if(e && u) {
       res.status(200) //Both available
    }
    else if (e && !u) {
       res.status(409) //"Email free, user taken"
    }
    else if (!e && u) {
       res.status(403) //"Email taken, user free"
    }
    else if (e!=null && u!=null) {
       res.status(418)
    }
  } catch(e) {
    res.status(500).json(e);
  }
});
0 голосов
/ 30 декабря 2018

Есть много вещей, которые меня не устраивают в отношении стиля и ясности написанного вами кода, но причина, по которой вы не получаете результатов во втором случае, заключается просто в том, что вы не возвращаетесь из своего usr() иeml() функции.Это должно быть решено префиксом return непосредственно перед Person.findOne(... строками.

0 голосов
/ 30 декабря 2018

Сначала вы либо придерживаетесь Promises или callbacks.

var usr = Person.findOne({username: req.query.u}).exec() // do not need a nodeback

Затем вы возвращаете функции неопределенными.Должен вернуть обещание правильно взаимодействовать с await

function usr() {
  // return!
  return Person.findOne({username: req.query.u}).exec()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...