如何使用 Bluebird 在构造函数上承诺导出的函数 "class"
How to use Bluebird to promisify the exported functions on a constructor-built "class"
我有一个服务,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 来 promisify 挂起 PageService 的所有方法(getAll、getById、创建、更新、删除等)。我已经查看了关于该主题的多个讨论,但大多数似乎都关注试图让构造函数 return 做出承诺。我只想承诺所有挂在 class 我通过构造函数创建的函数。这是 pageService = new PageService(database);我无法通过承诺。
PageService 仅使用基本的构造函数模式 - 例如
self.getAll = function(next) {
self.collection.find({}, function(err, docs) {
if (err) return next(err);
next(null, docs);
});
};
如果有人能告诉我正确的方法来轻松地 promisify 从构造函数 returned 对象挂起的所有函数,我将不胜感激。我也对我可能以错误的方式做这件事持开放态度。我对一般的承诺还很陌生,欢迎指导。
更新
我通过执行以下操作得到了承诺的功能...
pageService = new PageService(database);
Promise.promisifyAll(pageService);
... 但是,每次我新建一个服务实例时,通过承诺来 运行 似乎是一种不好的做法。我想要一种只承诺一次的方法。我认识到在服务中手动 returning promises 可能是解决方案,但我希望通过 bluebird magic 获得更优雅的东西。
你不应该担心每次promisification。它所做的只是将您的回调包装在适当的承诺代码中。无需担心性能损失,这是一个完全可以接受的解决方案。
也没有别的办法了。这一切都归结为两个解决方案:使用 Bluebird
promisification
或手动重写您的服务以使用 promises
.
页面服务模块:
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);
});
});
});
我有一个服务,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 来 promisify 挂起 PageService 的所有方法(getAll、getById、创建、更新、删除等)。我已经查看了关于该主题的多个讨论,但大多数似乎都关注试图让构造函数 return 做出承诺。我只想承诺所有挂在 class 我通过构造函数创建的函数。这是 pageService = new PageService(database);我无法通过承诺。
PageService 仅使用基本的构造函数模式 - 例如
self.getAll = function(next) {
self.collection.find({}, function(err, docs) {
if (err) return next(err);
next(null, docs);
});
};
如果有人能告诉我正确的方法来轻松地 promisify 从构造函数 returned 对象挂起的所有函数,我将不胜感激。我也对我可能以错误的方式做这件事持开放态度。我对一般的承诺还很陌生,欢迎指导。
更新
我通过执行以下操作得到了承诺的功能...
pageService = new PageService(database);
Promise.promisifyAll(pageService);
... 但是,每次我新建一个服务实例时,通过承诺来 运行 似乎是一种不好的做法。我想要一种只承诺一次的方法。我认识到在服务中手动 returning promises 可能是解决方案,但我希望通过 bluebird magic 获得更优雅的东西。
你不应该担心每次promisification。它所做的只是将您的回调包装在适当的承诺代码中。无需担心性能损失,这是一个完全可以接受的解决方案。
也没有别的办法了。这一切都归结为两个解决方案:使用 Bluebird
promisification
或手动重写您的服务以使用 promises
.
页面服务模块:
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);
});
});
});