如何使用 bluebird 来 promisify node-rest-client

how to use bluebird to promisify node-rest-client

我正在尝试对 node-rest-client 库进行 promisify(尝试过 restler,但似乎无法重入并导致对同一端点的并行 POST 出现问题)。

我尝试使用类似的方法来提供 restler 的 bluebird 文档中显示的 filter/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);

成功将 promisified 函数添加到 restClient

但是,当我调用 postAsync(url, options).then(...) 时,node-rest-client 库抛出一个错误,指出回调未定义。

据我所知,这应该可以工作,但承诺器中提供的回调函数似乎没有进入库。

我希望对 Bluebird 有更多经验的人能够看到我做错了什么。

.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);
        });
    };
}