【问题标题】:(node:3341) DeprecationWarning: Mongoose: mpromise(节点:3341)弃用警告:猫鼬:承诺
【发布时间】:2016-11-03 10:54:37
【问题描述】:

我正在尝试使用我的自定义方法在 mongoose 上开发一个类,所以我用我自己的类扩展了 mongoose,但是当我调用创建一个新的 car 方法时它可以工作,但是它的条带和错误,在这里我让你看看我在做什么。

我收到此警告

(node:3341) DeprecationWarning: Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html

之后

driver.createCar({
      carName: 'jeep',
      availableSeats: 4,
    }, callback);

driver 是 Driver 类的一个实例

const carSchema = new Schema({
  carName: String,
  availableSeats: Number,
  createdOn: { type: Date, default: Date.now },
});
const driverSchema = new Schema({
 email: String,
 name: String,
 city: String,
 phoneNumber: String,
 cars: [carSchema],
 userId: {
   type: Schema.Types.ObjectId,
   required: true,
 },
createdOn: { type: Date, default: Date.now },
});
const DriverModel = mongoose.model('Driver', driverSchema);

class Driver extends DriverModel {
  getCurrentDate() {
  return moment().format();
}
create(cb) {
  // save driver
  this.createdOn = this.getCurrentDate();
  this.save(cb);
}
remove(cb) {
  super.remove({
  _id: this._id,
 }, cb);
}
createCar(carData, cb) {
  this.cars.push(carData);
  this.save(cb);
}
getCars() {
  return this.cars;
 }
}

关于我做错了什么有什么想法吗?

【问题讨论】:

标签: node.js mongodb mongoose


【解决方案1】:

在阅读文档后,这对我来说是解决问题的方法: http://mongoosejs.com/docs/promises.html

文档中的示例使用的是 bluebird Promise 库,但我选择使用原生 ES6 Promise。

在我调用mongoose.connect的文件中:

mongoose.Promise = global.Promise;
mongoose.connect('mongodb://10.7.0.3:27107/data/db');

[编辑:感谢@SylonZero 在我的回答中提出了性能缺陷。由于这个答案受到了如此广泛的关注,因此我有责任进行此编辑并鼓励使用 bluebird 而不是原生承诺。请阅读下面的答案以获取更多受过教育和经验丰富的详细信息。 ]

【讨论】:

  • 在网站上验证了基准后:bluebirdjs.com/docs/benchmarks.html@SylonZero 指的是,我相信他的解决方案值得投票而不是第一个提案。我仍然感谢 Hunter Lester 所做的出色工作和调查并分享他的发现!
  • 感谢您的编辑,这让我意识到了一个巨大的性能缺陷
【解决方案2】:

虽然上述答案准确且有效,但如果您有一个真正的生产 Node 应用程序,则必须考虑性能问题。

上面的解决方案将使用原生 ES6 承诺 - 在我在下面分享的基准测试中,它比 bluebird 慢 4 倍。这可能会极大地影响用 Node 编写并使用 MongoDB 的 API 的性能。

我推荐使用 Bluebird:

// Assuming you store the library in a var called mongoose
var mongoose = require('mongoose');

// Just add bluebird to your package.json, and then the following line should work
mongoose.Promise = require('bluebird');

基准测试结果

平台:(在撰写本文时使用最新的节点)

  • Linux 4.4.0-59-generic x64
  • Node.JS 6.9.4
  • V8 5.1.281.89
  • Intel(R) Core(TM) i7-6500U CPU @ 2.50GHz × 4
  • 16 GB RAM 和 500 GB SSD

    | file                                      | time(ms) | memory(MB) |
    |-------------------------------------------|----------|------------|
    | callbacks-baseline.js                     | 114      | 25.09      |
    | callbacks-suguru03-neo-async-waterfall.js | 152      | 32.98      |
    | promises-bluebird-generator.js            | 208      | 29.89      |
    | promises-bluebird.js                      | 223      | 45.47      |
    | promises-cujojs-when.js                   | 320      | 58.11      |
    | promises-then-promise.js                  | 327      | 64.51      |
    | promises-tildeio-rsvp.js                  | 387      | 85.17      |
    | promises-lvivski-davy.js                  | 396      | 81.18      |
    | callbacks-caolan-async-waterfall.js       | 527      | 97.45      |
    | promises-dfilatov-vow.js                  | 593      | 148.30     |
    | promises-calvinmetcalf-lie.js             | 666      | 122.78     |
    | generators-tj-co.js                       | 885      | 121.71     |
    | promises-obvious-kew.js                   | 920      | 216.08     |
    | promises-ecmascript6-native.js            | 931      | 184.90     |
    | promises-medikoo-deferred.js              | 1412     | 158.38     |
    | streamline-generators.js                  | 1695     | 175.84     |
    | observables-Reactive-Extensions-RxJS.js   | 1739     | 218.96     |
    | streamline-callbacks.js                   | 2668     | 248.61     |
    | promises-kriskowal-q.js                   | 9889     | 410.96     |
    | observables-baconjs-bacon.js.js           | 21636    | 799.09     |
    | observables-pozadi-kefir.js               | 51601    | 151.29     |
    | observables-caolan-highland.js            | 134113   | 387.07     |

【讨论】:

  • 据我了解:您的基准来自哪里?围绕这些结果是否达成共识?似乎每个人都在投票支持默认的 ES6 承诺答案,但我想更深入地研究你提到的性能问题。
  • 基准测试来自一套测试,您可以从 bluebird git repo 读取(和审查)这些测试 - 我在本地再次运行它们以获得上述结果,因为我需要 2017 年的结果与他人分享。更重要的是,我在我们自己的 API 中体验到了性能提升(我有 5 个微服务和一个严格的可扩展性目标),并且不得不经常决定使用简单的嵌套回调而不是 promise(仍然是最快的)。我个人认为基准测试只是迈向决策的第一步,但我还不能分享我的内部数据……我的规模目标是每台物理机 10K 用户。
  • 此外,点赞数几乎不能完全衡量答案。根据我的经验,很多人在解决问题后很少深入挖掘(或阅读其他任何内容),而且我过去指导过的许多程序员都需要了解代码的性能和仪表技能。
  • 非常感谢您提出性能问题。我是一个新手程序员,只有 2 年的时间,并且渴望接受这种教育。我在生产中使用它,所以我更高兴知道是否它。对程序和代码段进行基准测试的最佳方法是什么?
  • Hunter,这将取决于平台和代码的性质,但与这个问题有关:获得洞察力有两个方面 - 1. 通过负载生成器使用好的测试来模拟用户请求.我使用 Apache jMeter 来测试我的 Node API 并为多个用户生成负载。 2. Instrumentation:你如何跟踪单个交易。我使用 NewRelic 来检测我的节点代码——它以毫秒为单位提供了每笔交易的详细细分(包括 Express 路由、Mongo 查询时间、Redis 会话等)。希望这能让你开始。
【解决方案3】:

你试过了吗? 例如:

const mongoose = require('mongoose')
mongoose.Promise = global.Promise // <--
const Schema = mongoose.Schema
const UserSchema = new Schema({
  name: String,
})
const User = mongoose.model('user', UserSchema)
module.exports = User

如果您从未重新定义承诺的 mongoose 实例创建模型 - 此模型上的每个查询都会引发警告。

【讨论】:

    【解决方案4】:

    我想你有你的答案,但我使用 global.promise 处理错误

    // MongoDB connection
    mongoose.Promise = global.Promise;
    
    var promise = mongoose.connect('mongodb://localhost:27017/test_db', {
      useMongoClient: true,
    });
    
    promise.then(function(db) {
        console.log("Connected to database!!!");
    }, function(err){
        console.log("Error in connecting database " + err);
    });
    

    【讨论】:

      【解决方案5】:
      var mydb;
      var uri = 'mongodb://localhost/user1';
      var promise = mongooose.connect(uri,{
            useMongoClient: true,
      });
      promise.openUri(uri,function(errr,db){
      if(errr){
              throw errr;
            }else{
              console.log("Connection Successfull");      
              mydb = db;
            }
      });
      

      在最新版本的猫鼬中,需要借助 Promise 建立联系 [这是链接][1] [1]:http://mongoosejs.com/docs/promises.html

      【讨论】:

        【解决方案6】:

        只需将第二个参数作为对象添加到 connect() 方法即可。

        mongoose.connect('dbUrl', {
          useMongoClient: true
        });
        

        见:http://mongoosejs.com/docs/connections.html#use-mongo-client

        【讨论】:

        • 仅此一项并不能消除警告。如上所述,我们还需要映射全球承诺。
        【解决方案7】:

        猫鼬 4.8.6

        如果你发现这样的错误:

        (node:9600) DeprecationWarning: Mongoose: mpromise (mongoose 的默认 承诺库)已弃用,插入您自己的承诺库 改为:http://mongoosejs.com/docs/promises.html

        您还需要设置用于驱动程序的承诺库的选项。

        mongoose.Promise = global.Promise
        mongoose.connect(uri, { useMongoClient: true, options: { promiseLibrary: mongoose.Promise }})
        

        【讨论】:

          【解决方案8】:
          var mongoose = require('mongoose');
          mongoose.Promise = global.Promise;
          db = mongoose.connect(env.DATABASE_URI, function(){
            //
          })
          

          这对我有用。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-05-12
            • 2021-03-05
            • 1970-01-01
            • 2014-03-27
            • 2012-12-14
            • 2017-06-15
            • 2019-06-04
            相关资源
            最近更新 更多