【问题标题】:Using a promise with a 'require' to dynamically load module使用带有“要求”的承诺来动态加载模块
【发布时间】:2017-01-17 21:04:29
【问题描述】:

我正在使用 mongoose 并尝试使用“require”动态加载架构/模型,但出现异常行为。更具体地说,“要求”在承诺链完成后执行,这不是我所期望的。相反,我希望完成同步的“要求”(据我所知),然后按顺序调用 promise.resolve 以维护承诺链。

(注:我认为mongoose不涉及这个问题,但在这个例子中用于说明问题)

我的代码(简化以说明问题)如下:

var Promise = require('bluebird');
var mongoose = require('mongoose');

function connect(){
  console.log('Connecting');
  return new Promise(function(resolve,reject){
    mongoose.connect('mongodb://localhost/mongodb');
    mongoose.connection.on('connected', function () {
        resolve();
    });
  });
}

function configure(fileName){
  console.log('Configuring filename: %s', fileName);
  return new Promise(function(resolve,reject){
    console.log('Requiring filename: %s', fileName);
    require(filename);
    console.log('Required filename: %s', fileName);
    resolve();
  });
}

function findAll(modelName){
  console.log('Finding');
  mongoose.model(modelName).find(function(err, data) {
    console.log('Model: %s, found items: %s', modelName, data);
  });
}

var modelName = 'users';
var modelFile = './' + modelName;
connect()
  .then(function(){
    configure(modelFile);
  })
  .then(function(){
    findAll(modelName);
  })
  .catch(function(err){
    console.log('Mainline promise error: %s', err.stack);
    process.exit(0);
  });

包含架构和模型创建(在“require”中加载)的模块(“users.js”)如下所示。请注意,由于“要求”未完成,我假设此模块未加载,但为了完整起见,我已将其包含在内:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

console.log('users schema starting');
var schema = new Schema({
  firstname: String,
  lastname: String,
  middlename: String
});

var users = mongoose.model('users', schema);
console.log('users schema defined');

module.exports = users;

下面的控制台消息说明“require”似乎执行不按顺序执行(即“require”开始,随后的promise 已解决,但“require”没有同步完成)。因此,当“查找”发生时,架构/模型不可用:

Connecting
Configuring filename: ./users
Requiring filename: ./users
Finding
Mainline promise error: MissingSchemaError: Schema hasn't been registered for model "users".
Use mongoose.model(name, schema)
    at Mongoose.model ({user-dir}node_modules/mongoose/lib/index.js:349:13)
    at findAll ({user-dir}main.js:28:14)
    at {user-dir}main.js:40:9
    at tryCatcher ({user-dir}node_modules/bluebird/js/main/util.js:26:23)
    at Promise._settlePromiseFromHandler ({user-dir}node_modules/bluebird/js/main/promise.js:507:31)
    at Promise._settlePromiseAt ({user-dir}node_modules/bluebird/js/main/promise.js:581:18)
    at Promise._settlePromises ({user-dir}node_modules/bluebird/js/main/promise.js:697:14)
    at Async._drainQueue ({user-dir}node_modules/bluebird/js/main/async.js:123:16)
    at Async._drainQueues ({user-dir}node_modules/bluebird/js/main/async.js:133:10)
    at Immediate.Async.drainQueues [as _onImmediate] ({user-dir}node_modules/bluebird/js/main/async.js:15:14)
    at processImmediate [as _immediateCallback] (timers.js:383:17)    

感谢任何有关解决方案或替代方法的见解。

【问题讨论】:

    标签: node.js mongoose promise


    【解决方案1】:

    您需要返回在您的thens 中创建的承诺。现在,您正在为 connect 解析时注册两个回调,但从未为 configurefindAll 承诺注册任何回调。

    connect()
    .then(function(){ // called when connect resolves
      configure(modelFile); // creates a new promise
    })
    .then(function(){ // called when connect resolves and the previous function returns
      findAll(modelName);
    })
    

    如果您将其更改为:

    connect()
    .then(function(){
      return configure(modelFile);
    })
    .then(function(){ // called when the promise from the previous function resolves
      return findAll(modelName);
    })
    

    您应该会看到所需的行为。

    【讨论】:

      猜你喜欢
      • 2017-10-07
      • 2011-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-23
      • 1970-01-01
      • 2017-06-25
      • 1970-01-01
      相关资源
      最近更新 更多