我试图宣传node-rest-client库(尝试使用restler,但似乎不会重入,并导致并行POST到同一端点的问题)。
我尝试对蓝莓文档中显示的提供过滤器/ promisifer使用类似的方法,但是似乎无法使其正常工作。
node-rest-client使用回调函数和两个参数的组合来成功响应,同时还为超时和错误提供事件发射器。
var Promise = require("bluebird");
var methodNamesToPromisify = "get post put del patch".split(" ");
function EventEmitterPromisifier(originalMethod) {
// return a function
return function promisified() {
var args = [].slice.call(arguments);
var self = this;
return new Promise(function(resolve, reject) {
var emitter = originalMethod.apply(self, args, function(data, response){
resolve([data, response]);
});
emitter
.on("error", function(err) {
reject(err);
})
.on("requestTimeout", function() {
reject(new Promise.TimeoutError());
})
.on("responseTimeout", function() {
reject(new Promise.TimeoutError());
});
});
};
};
exports.promisifyClient = function(restClient){
Promise.promisifyAll(restClient, {
filter: function(name) {
return methodNamesToPromisify.indexOf(name) > -1;
},
promisifier: EventEmitterPromisifier
});
}
以及代码中的其他地方:
var Client = require('node-rest-client').Client;
var constants = require('../../config/local.env');
var restClient = new Client();
promisifyClient(restClient);
成功地将已宣传的功能添加到restClient
但是,当我调用postAsync(url, options).then(...)
时,node-rest-client库会抛出一个错误,指出回调未定义。
到目前为止,我可以看到这应该可行,但似乎promisifier中提供的回调函数并没有通过库。
我希望有更多Bluebird经验的人能够看到我做错了什么。
答案 0 :(得分:1)
.apply
method只接受两个参数 - this
上下文和一个参数数组 - 但是你传递的是三个。
您需要将回调放到数组上,以将其作为originalmethod
的最后一个参数传递:
function EventEmitterPromisifier(originalMethod) {
return function promisified() {
var args = [].slice.call(arguments),
self = this;
return new Promise(function(resolve, reject) {
function timeout() {
reject(new Promise.TimeoutError());
}
args.push(function(data, response){
resolve([data, response]);
});
originalMethod.apply(self, args)
// ^^^^
.on("error", reject)
.on("requestTimeout", timeout)
.on("responseTimeout", timeout);
});
};
}