如何创建一个返回等待EventEmitter的promise的函数?

时间:2015-12-18 00:38:55

标签: javascript javascript-events promise

使用使用EventEmitters的JS库来调用结果是在调用启动函数后返回的,如何使用调用启动函数的函数来包装库,然后返回等待发出的事件的Promise?

更新:在此示例中,唯一标识符用于匹配具有返回结果的请求。

例如:

var Class = (function() {

    Class = function() {
        self = this
        self.transactionid = undefined
        self.result = undefined

        self.client = new Client({
            clientId: 0,
            host: '127.0.0.1',
            port: 4001
        }).on('received', function (tokens) {
            console.info('%s %s', '<<< RECV <<<'.cyan, JSON.stringify(tokens))

            // I wish to return `tokens` here via the promise
            if( tokens[ 0 ] == self.transactionid ) 
              self.result = tokens[ 1 ]

        }).on('sent', function (tokens) {
            console.info('%s %s', '>>> SENT >>>'.yellow, JSON.stringify(tokens))
        })

        self.client.connect()

    }

    Class.prototype.request = function( id ) {
        return $q( function( resolve, reject ) {

            self.transactionid = 1000
            self.client.requestData( transactionid, { key: '1234' }, '', false)

            var data = '<want to wait for / return token data here>'            

            // possibly use a dictionary to track different transactions and results?

            resolve( data )
        })
    }

    return Class

})()

1 个答案:

答案 0 :(得分:1)

如果您改写&#34;通过承诺&#34;返回tokens,作为&#34;解决与此交易ID相关的延期&#34;,那么您最终得到的东西非常像常规承诺缓存 - 除此处需要延迟缓存。

幸运的是,$ q(像Q一样,但不像Bluebird或本地承诺)为这样的情况提供Deferreds,其中Promise创建和Promise结算松散耦合或以其他方式错位。

var Class = (function() {
    Class = function() {
        self = this;
        self.transactions = {}; // a cache of Deferred objects
        self.client = new Client({
            clientId: 0,
            host: '127.0.0.1',
            port: 4001
        }).on('received', function (tokens) {
            console.info('%s %s', '<<< RECV <<<'.cyan, JSON.stringify(tokens));
            self.transactions[tokens[0]].resolve(tokens[1]);
        }).on('sent', function(tokens) {
            console.info('%s %s', '>>> SENT >>>'.yellow, JSON.stringify(tokens));
        });
        self.client.connect();
    };
    Class.prototype.request = function(id) {
        if(!this.transactions[id]) {
            this.transactions[id] = $q.defer();// a Deferred object to be deferred in the onReceived handler
            this.client.requestData( id, { key: '1234' }, '', false);
        }
        return this.transactions[id].promise;
    }
    return Class;
})();

错误处理似乎是一个更大的问题。您可以重新引入onerror处理程序,但除非其error对象包含id属性,否则您无法从this.transactions中检索相应的Deferred。

所以,要么:

  • 修改Client()类以提供具有id属性的错误对象。
  • 创建请求的地方,在超时后拒绝延迟。

甚至可能都是上述两种情况。