Javascript async ждут не ждут мангуста ждут - PullRequest
0 голосов
/ 09 декабря 2018

Я пытаюсь переместить вызовы базы данных из моего контроллера, чтобы очистить вещи и сделать их тестируемыми.Когда они находятся в контроллере, все движется плавно.Я переместил их из контроллера и добавил асинхронный режим, чтобы мы подождали.В противном случае я бы вызвал функцию res.render() в пределах .exec() из Users.findOne().Теперь, когда я использую async / await, функция в моем контроллере считает, что пользователя нет, потому что он не ждет.

На SO есть несколько вопросов относительно асинхронного ожидания, но я не нашел ни одного, который бы разрешил мою проблему.Я проверил, что мой пользователь вернулся, и добавил журналы консоли, чтобы показать путь.

  • узел mongoose async await показался многообещающим, но их настоящей проблемой была неспособность вернуть элемент, и моя вернулась в порядке
  • асинхронность не ожидалаawait - проблема с kotlin
  • async, ожидайте, не ожидая Кажется очень применимым, но я не полностью понимаю ответ о вложенном await / async - проблема, которую задавал задающий вопрос, была болеесложнее, чем мой запрос, потому что они имеют дело с циклами и forEach
  • Javascript async await на месте, поэтому я проверил, что функция mongoose возвращает обещание.Документы Mongoose показывают, что он готов к асинхронному вызову, потому что вызовы возвращают обещание.

Предположим, что мы разрешаем маршрут /users

маршруты / index.js

// requires & other routes not shown 
router.get('/users', controller.testUserShow);

контроллеры / индекс.js

// requires & other routes not shown 
   exports.testUserShow = async (req, res, next) => {
      if (req.user) { // if code to get user is right here, with no async/await, the user is found and the code continues
        try {
          found = await services.fetchUser(req.user._id)
          console.log("I am not waiting for at testusershow")
          console.log(found); //undefined
          // go on to do something with found
        } catch(e) {
          throw new Error(e.message)
        }
      }
    }

services / index.js

const db = require('../db')
exports.fetchUser = async (id) => {
  try {
    console.log("fetchUser is asking for user")
    return await db.returnUser(id)
  } catch(e) {
    throw new Error(e.message)
  }
}

db / index.js

const User = require('../models/user');
exports.returnUser = async (id) => {
  User.findById(id)
      .exec(function(err, foundUser) {
          if (err || !foundUser) {
              return err;
          } else {
              // if this was in the controller 
              // we could res.render() right here
              console.log("returnUser has a user");
              console.log(foundUser); // this is a User
              return foundUser;
          }
      });
}

Журнал консоли отправляется

fetchUser is asking for user
I am not waiting for at testusershow
undefined
returnUser has a user
// not printed... valid user 

Я ожидаю, что начальный вызов будет неопределенным, если я вызываю что-то, что не возвращает обещание, но User.findOne() должно.

Что мне здесь не хватает?

Ответы [ 2 ]

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

Ваш db/index должен выглядеть следующим образом:

exports.returnUser = (id) => {
  return User.findById(id);
}

Когда вы не вызываете exec, он вернет обещание.И поскольку ваш services/index.js уже использует await для получения ответа, db/index не обязательно должно быть асинхронной функцией.

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

Это самый простой способ:

const User = require('../models/user');
exports.returnUser =  (id) => {
   return User.findById(id).exec().then(foundUser => { 
          console.log(foundUser); // this is a User
          return foundUser;
  });
}

, если вы хотите использовать async / await, тогда вы можете сделать:

    exports.returnUser = async id => {
       const foundUser = await User.findById(id).exec();
       console.log({foundUser});
       return foundUser;
      });
    }

, и если вы хотите использовать обратные вызовы, это будетвыглядит так:

exports.returnUser =  (id, cb) => {
   return User.findById(id).exec(cb);
}

классная мысль о Mongoose заключается в том, что если вы не передадите обратный вызов, он вернет обещание из функции / метода exec.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...