возвращаемое значение обещания

Я новичок в обещаниях, и я пытаюсь вернуть значение обещания, как это делает мангуст, но с использованием монгоскина и синей птицы. Это работает с мангустом return User.find().then(users => users). Это вернет список пользователей, а не обещание в преобразователях серверов apollo.

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

mongodb.js

import Promise from 'bluebird';
import mongoskin from 'mongoskin';

Object.keys(mongoskin).forEach(function (key) {
  var value = mongoskin[key];
  if (typeof value === 'function') {
    Promise.promisifyAll(value);
    Promise.promisifyAll(value.prototype);
  }
});

Promise.promisifyAll(mongoskin);

export default {
  connect (uri) {
    return mongoskin.db(uri, {native_parser:true});
  }
};

пользователи.js

import mongodb from '../../databases/mongodb';

export default class User {
  constructor () {
    this.db = mongodb.connect('mongodb://127.0.0.1:27017/test', {native_parser:true});
    this.collection = this.db.collection('users');
  }

  find (query = {}, options = {}) {
    const findAsync = () => {
      return Promise.resolve().then(() => {
        return this.collection.findAsync(query, options);
     })
     .then((xx) => {
        xx.toArray((err, items) => {
         if (err) return err;
        return items;
       });
     });

    };

    async function getData () {
      let foo = await findAsync();

      return foo;
    }

    return getData();
  }
}

const user = new User();

function bar () {
  return user.find().then(x => console.log(x));
}

console.log(bar());

person otissv    schedule 10.06.2016    source источник
comment
User.find().then(users => users) действительно возвращает обещание.   -  person robertklep    schedule 10.06.2016
comment
Это может быть связано с тем, что я использую его с сервером apollo. я отредактирую вопрос   -  person otissv    schedule 10.06.2016


Ответы (1)


Ваш код кажется слишком сложным. Я думаю, что вы хотите это (я не обещал mongoskin, потому что это не очень хорошо подходит для этого; см. ниже):

export default class User {
  constructor() {
    this.db         = mongoskin.connect(...);
    this.collection = this.db.collection('users');
  }

  find (query = {}, options = {}) {
    return new Promise((resolve, reject) => {
      this.collection.find(query, options).toArray((err, items) => {
        if (err) return reject(err);
        resolve(items);
      });
    });
  }
}

Я должен сказать, что Mongoskin чувствует себя довольно устаревшим. Это скин поверх официального драйвера mongodb, который в настоящее время довольно приличный (он поддерживает готовые обещания, например, то, что Mongoskin не распространяет).

Если вы хотите обещать, то я должен сказать, что следующий анти-шаблон обещания:

return Promise.resolve().then(() => {
  return this.collection.findAsync(query, options);
}).then(...)

Вы можете переписать это так:

return this.collection.findAsync(query, options).then(...);

Однако toArray() снова усложняет ситуацию, потому что для этого вам делает нужно создать новое обещание, поэтому код становится примерно таким:

return this.collection.findAsync(query, options).then((cursor) => {
  return new Promise((resolve, reject) => {
    cursor.toArray((err, items) => {
      if (err) return reject(err);
      resolve(items);
    });
  });
});

Что выглядит не очень красиво, поэтому я решил не обещать и просто использовать обратные вызовы в этом случае (хотя я уверен, что у Bluebird есть несколько хороших инструментов, которые могут облегчить просмотр приведенного выше кода, но все же... ).

person robertklep    schedule 10.06.2016
comment
Спасибо за объяснение и упрощение моего кода. Попробую использовать родной драйвер. Я думаю, что это может быть сервер apollo, поскольку он принимает обещание, но, похоже, не выполняет, если только я не использую мангуста, а не так, как я это делаю. Попробую спросить на их канале. - person otissv; 11.06.2016