简体   繁体   English

承诺的回报价值

[英]return value of promise

Im new to promises and I'm trying to to return the value of a promise like mongoose does but using mongoskin and bluebird. 我对诺言很陌生,我正试图像猫鼬一样返回诺言的价值,但要使用mongoskin和bluebird。 This works with mongoose return User.find().then(users => users) . 这适用于猫鼬return User.find().then(users => users) This will return a list of users not a promise in apollo-server resolvers. 这将返回用户列表,而不是apollo服务器解析器中的承诺。

I've tried promise generator and async but with no luck. 我已经尝试了Promise Generator和Async但没有运气。 From what I've read a promise always returns a promise so no idea how mongoose is returning a value. 从我读过的书中,一个诺言总是会返回一个诺言,所以不知道猫鼬如何返回一个值。

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

Your code seems overly complicated. 您的代码似乎过于复杂。 I think what you want is this (I didn't promisify mongoskin because it's not very well suited for that; see below): 我认为您想要的是这个(我没有承诺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);
      });
    });
  }
}

I have to say that Mongoskin feels pretty outdated. 我不得不说,Mongoskin感觉已经过时了。 It's a skin on top of the official mongodb driver, which is pretty decent nowadays (it supports promises out-of-the-box, for one, something that Mongoskin doesn't propagate). 它是官方mongodb驱动程序之上的皮肤,如今非常不错(它支持开箱即用的Promise,其中一个是Mongoskin不会传播的东西)。

If you do want to promisify, then I should say that the following is a promise anti-pattern: 如果您确实要承诺,那么我应该说以下是一个承诺反模式:

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

You can rewrite it to this: 您可以将其重写为:

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

However, the toArray() makes things difficult again, because for that you do need to create a new promise, so the code becomes something like this: 但是, toArray()再次使事情变得困难,因为为此您确实需要创建一个新的Promise,因此代码变为如下所示:

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

Which doesn't look very pretty at all, hence my choice to not promisify and just use callbacks in this case (although I'm sure that Bluebird has some nice tools that may the above code easier to look at, but still...). 看起来一点都不漂亮,因此我选择不发散,在这种情况下只使用回调(尽管我确信Bluebird有一些不错的工具,上面的代码可能更容易看,但仍然... )。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM