如何使用Bluebird在构造函数构建的“类”上宣传导出的函数

时间:2015-07-25 05:31:16

标签: javascript promise bluebird

我有一个服务,PageService,我这样测试(简化)......

var database = require("../database/database");
var PageService = require("./pageService");

describe("PageService", function () {
    var pageService = {};

    before(function (done) {
        pageService = new PageService(database);
    }

    it("can get all Pages", function (done) {
        pageService.getAll(function (err, pages) {
            if (err) return done(err);

            pages.should.be.instanceOf(Array);
            pages.length.should.be.greaterThan(1);
            done();
    });
});

我一直在努力使用bluebird来宣传所有悬挂在PageService上的方法(getAll,getById,create,update,delete等)。我已经看了几个关于这个主题的讨论,但大多数似乎都在关注试图让构造函数返回一个承诺。我只想通过构造函数来宣传我创建的类中的所有函数。它是pageService = new PageService(数据库);我无法通过宣传。

PageService只使用基本的构造函数模式 - 例如

self.getAll = function(next) {
    self.collection.find({}, function(err, docs) {
        if (err) return next(err);

        next(null, docs);
    });
};

如果有人能告诉我正确的方法来轻松地宣传从构造函数返回的对象的所有函数,我会很感激。我也很乐意接受这样一个事实:我可能以错误的方式这样做。我对一般的承诺很新,并欢迎指导。

更新

通过执行以下操作,我获得了承诺的功能......

pageService = new PageService(database);
Promise.promisifyAll(pageService);

...但是每次我新建一个服务实例时,这都是一种不好的做法。我想要一种方式来宣传一次,只有一次。我认识到手动返回服务中的承诺可能是解决方案,但希望通过蓝鸟魔法更优雅。

2 个答案:

答案 0 :(得分:3)

PageService模块:

function PageService(collection) {
    this.collection = collection;
}
PageService.prototype.getAll = function(next) {
    this.collection.find({}, function(err, docs) {
        if (err) return next(err);
        next(null, docs);
    });
};

module.exports = PageService;

测试模块

var should = require("should");
var Promise = require("bluebird");
var database = { // mockup
    find: function (options, next) {
        next(null, ['the', 'list', 'of', 'docs']);
    }
};
var PageService = require("./PageService");

Promise.promisifyAll(PageService.prototype);

describe("PageService", function () {
    var pageService;

    before(function () {
        pageService = new PageService(database);
    });

    it("can get all pages", function () {
        return pageService.getAllAsync()
        .then(function (pages) {
            pages.should.be.instanceOf(Array);
            pages.length.should.be.greaterThan(1);
        });
    });
});

答案 1 :(得分:1)

每次都不应该关注 promisification。它所做的只是将回调包装在适当的承诺代码中。没有性能损失需要关注,这是一个完全可以接受的解决方案。

也没有其他方法可以做到这一点。这一切都归结为两种解决方案:使用var classified = Classifier.classifyToCharacterOffsets(docText).toArray(); Bluebird或手动重写您的服务以使用promisification