allishappy
@allishappy

Как правильно написать функцию для получения пользователя?

Здравствуйте. Хочу написать функцию, которая принимает БД, id юзера, коллекцию и возвращает пользователя в виде объекта. Из-за асинхронности ноды ничего не получается. Как поправить?

function getUser(db, id, collection) {
  let a;
  db.open(function(err, db) {
    if (err) throw err;
    let users = db.collection(collection);
      let cursor = users.find({telegramId:id});
      a = cursor;
        cursor.toArray(function(err, results) {
          if (err) throw err;
          db.close();
        });
  });

  return a;
};
  • Вопрос задан
  • 246 просмотров
Пригласить эксперта
Ответы на вопрос 2
@Atllantis
Из-за асинхронности ноды ничего не получается
Для того и были придуманы калбеки!
Ответ написан
mannaro
@mannaro
Умею профессионально гуглить
Раз уж используете ES6 (let), то юзайте промисы:

function proxy(fn, ...args) {
  return new Promise((res, rej) => {
    fn(...args, (err, result) => {
      if (err) rej(err);
      else res(result);
    });
  });
}

function getUser(db, id, name) {
  var _db;

  var result = proxy(db.open.bind(db)).then(db => {
    _db = db;
    var collection = db.collection(name);
    var cursor = collection.find({
      telegramId: id
    });
    return proxy(cursor.toArray.bind(cursor))
  }).catch(err => {
    console.error(err);
    _db.close();
  });

  result.then(() => _db.close());

  return result;
}

getUser(db, 'user-1', 'users').then(arr => {
  console.log('users: ', arr);
});


Тогда можно дальше преобразовать это к генераторам:
// подключаем npm-библиотеку co
var co = require('co');

function proxy(fn, ...args) {
  return new Promise((res, rej) => {
    fn(...args, (err, result) => {
      if (err) rej(err);
      else res(result);
    });
  });
}

function getUser(db, id, name) {
  var _db;

  var result = proxy(db.open.bind(db)).then(db => {
    _db = db;
    var collection = db.collection(name);
    var cursor = collection.find({
      telegramId: id
    });
    return proxy(cursor.toArray.bind(cursor))
  }).catch(err => {
    console.error(err);
    _db.close();
  });

  result.then(() => _db.close());

  return result;
}

// основная работа приложения будет тут
co(function*() {
  var users = yield getUser(db, 'user-1', 'users');
  console.log('users: ', users);
}).catch(err => {
  console.error('Произошла страшная ошибка!', err);
});


Но я бы на вашем мете еще сделал какую-то функцию, которая будет открывать соединение с БД и не закрывать его. Ибо каждый раз открывать/закрывать соединение с БД - очень дорогая операция.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы