【问题标题】:return value of promise承诺的返回值
【发布时间】:2016-10-11 20:58:13
【问题描述】:

我是 Promise 的新手,我正在尝试像 mongoose 一样返回 Promise 的值,但使用的是 mongoskin 和 bluebird。这适用于猫鼬return User.find().then(users => users)。这将返回用户列表,而不是 apollo-server 解析器中的承诺。

我尝试过承诺生成器和异步,但没有成功。从我读过的内容来看,一个承诺总是返回一个承诺,所以不知道猫鼬是如何返回一个值的。

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});
  }
};

users.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());

【问题讨论】:

  • User.find().then(users => users) 确实返回一个承诺。
  • 这可能是因为我将它与 apollo-server 一起使用。我将编辑问题

标签: javascript promise bluebird


【解决方案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 有一些不错的工具可以让上面的代码更容易查看,但仍然...)。

【讨论】:

  • 感谢您的解释和简化我的代码。将尝试使用本机驱动程序。我认为这可能是阿波罗服务器,因为它接受了一个承诺,但似乎并没有实现,除非我很好地使用猫鼬而不是我这样做的方式。我会尝试在他们的频道中询问。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-30
  • 1970-01-01
  • 2016-06-15
  • 1970-01-01
  • 2015-02-13
  • 1970-01-01
相关资源
最近更新 更多