【问题标题】:How to add Promise to event handler in javascript如何在 javascript 中将 Promise 添加到事件处理程序
【发布时间】:2015-03-11 03:57:44
【问题描述】:

现在我想用 Promise Q 包装 amqp,这里是代码

Sender.prototype.createConnection_ = function () {
    var deferred = Q.defer();
    this.con_ = amqp.createConnection( this.connectOpt_, this.implementOpt_ );
    deferred.resolve( this.con_ );

    return deferred.promise;
}

Sender.prototype.connectionReady_ = function() {
    var deferred = Q.defer(),
      self = this;

    self.con_.on('ready', function() {
        console.log('connection is ok now');
        deferred.resolve(self.con_);
    });
    return deferred.promise;
}

Sender.prototype.createExchange_ = function() {
    var deferred = Q.defer(),
      self = this;

    this.con_.exchange( this.exchangeName_, this.exchangeOpt_, function ( ex ) {
        self.ex_ = ex;
        deferred.resolve(self.ex_);
    });
    return deferred.promise;
}

Sender.prototype.exchangeReady_ = function() {
    var deferred = Q.defer(),
      self = this;

    this.ex_.on('open', function() {
        console.log('Sender: exchange opened');
        deferred.resolve(this.ex_);
    });
    return deferred.promise;
}

Sender.prototype.connect_ = function() {
    var self = this;
    return self.createConnection_()
            .then( self.connectionReady_() )
            .then( self.createExchange_() )
            .then( self.exchangeReady_() )
            .catch( function(err) {
                console.info( err );
            });
}

当我想调用connect_时,在exchangeReady_函数中有一个错误显示this.ex_null

我想在事件openready函数中如何添加Q

【问题讨论】:

  • 如果您愿意使用现代的 Promise 库,您可以摆脱答案中丑陋的 .binds。 (可能还有更好的性能)
  • 你能给我一些现代的 promise 库吗?
  • 例如,Bluebird 是最快的,并且有能力处理这个问题。

标签: javascript node.js promise amqp q


【解决方案1】:

您正在立即调用您的函数,而不是将函数引用传递给.then() 处理程序。 .then() 接受一个函数引用,而不是一个承诺作为参数。改为:

Sender.prototype.connect_ = function() {
    return this.createConnection_()
            .then( this.connectionReady_.bind(this) )
            .then( this.createExchange_.bind(this) )
            .then( this.exchangeReady_.bind(this) )
            .catch( function(err) {
                console.info( err );
            });
}

.bind(this) 允许您传递函数引用(.then() 基础架构可以稍后调用)并且仍然将其绑定到 this


当您像这样传递回调时,您可能还会遇到绑定问题:

amqp.createConnection( this.connectOpt_, this.implementOpt_ );

这些回调不会一直绑定到this。相反,在任何回调方法上使用 .bind() 这样的方法:

amqp.createConnection( this.connectOpt_.bind(this), this.implementOpt_.bind(this) );

您的代码中的其他几个地方也存在同样的问题。

【讨论】:

  • 添加了另一个传递回调时对象绑定问题的示例。
  • 那么.bind返回的函数?
  • @BenjaminGruenbaum - 我的错误。这将返回一个承诺,而不是一个函数。我将撤回我原来的评论。 self 可以删除。
猜你喜欢
  • 2014-08-03
  • 2012-02-04
  • 1970-01-01
  • 2021-02-26
  • 2018-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-01
相关资源
最近更新 更多