如何使用bluebird来宣传node-rest-client

时间:2015-05-07 22:20:41

标签: javascript node.js bluebird

我试图宣传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经验的人能够看到我做错了什么。

1 个答案:

答案 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);
        });
    };
}