【问题标题】:Using mongoose middleware to add async virtuals使用 mongoose 中间件添加异步虚拟
【发布时间】:2011-12-29 18:35:07
【问题描述】:

在 node.js / Mongoose 项目中,我有一个包含对外部图像文件的引用的架构。

var PageSchema = new Schema({
    title: String
  , media: {
        digest: String
      , name: String
    }
});

这些文件具有存储在文件本身中的附加属性:url、宽度、高度、exif 字段等。这些字段需要在模型发送到 res.render() 之前填充。

对于某些领域,事情是同步的,虚拟只是完成这项工作:

PageSchema.virtual('media.url').get(function () {
    return appPaths.fileUrl(this.media);
});

但是,宽度/高度或 exif 字段需要异步调用。我想过使用中间件来填充它们,但这似乎不起作用:

PageSchema.post('init', function(next) {
    var media = this.media;
    var fileName = filedb.absoluteFilePath(media);

    im.identify(fileName, function(err, features) {
        if (err) {
            media.width = 0;
            media.height = 0;
        } else {
            media.width = features.width;
            media.height = features.height;
        }

        next();
    });
});

我做错了什么?是否有解决此类问题的通用设计模式? (除了在数据库中复制这些信息?)

【问题讨论】:

    标签: node.js mongoose


    【解决方案1】:

    这里真正的问题是猫鼬目前似乎有一个不稳定的post 回调实现。虽然pre('init',function(next){ ... }); 可以按预期工作,但post('init',function(next){ ... }); 实际上并没有通过next 函数。事实上,post init 回调在调用时不会接收任何参数。

    因此,我通常为我的查询回调编写一个包装器来制作一种 DIY 中间件:

    var setAsyncVirtuals = function(callback){
      return function(err, docs){
        if(err) return callback(err);
        var i = done = docs.length;
        if(i > 0)
          while(i--){
            (function(i){
              var filename = getFilename();
              im.identify(filename, function(err, features) {
                if (err) {
                  docs[i].media.width = 0;
                  docs[i].media.height = 0;
                } else {
                  docs[i].media.width = features.width;
                  docs[i].media.height = features.height;
                }
                done--;
                if(done <= 0) callback(null, docs);
              });
            })(i); // bind i to hold value for async call
          }
        else callback(null, docs);
      }
    }
    

    然后

    Page.find({}, setAsyncVirtuals(function(err,docs){
      res.send(docs); // these have media.width & media.height assigned
    }));
    

    【讨论】:

      猜你喜欢
      • 2013-01-30
      • 2011-08-29
      • 2013-08-31
      • 2019-01-05
      • 2012-10-28
      • 2020-12-08
      • 1970-01-01
      相关资源
      最近更新 更多