javascript - 如何创建一个返回等待 EventEmitter 的 Promise 的函数?

标签 javascript promise dom-events

当使用使用 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

})()

最佳答案

如果您将“通过 Promise 返回 token ”改写为“解析与此事务 ID 关联的 Deferred”,那么您最终会得到非常类似于常规 Promise 缓存的内容 - 除了这里的需要延迟缓存。

幸运的是,$q(类似于 Q,但与 Bluebird 或原生 Promise 不同)为这种情况提供了 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 属性,否则您没有 key 从 this.transactions 检索相应的 Deferred 。

所以,要么:

  • 修改 Client() 类以传递带有 id 属性的错误对象。
  • 在创建请求的地方,超时后拒绝 Deferred。

也许以上两者都有。

关于javascript - 如何创建一个返回等待 EventEmitter 的 Promise 的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34346822/

相关文章:

javascript - 使用 promise 实现回退

javascript - 可以防止 Enter 仅从某些输入字段在 JavaScript 中提交表单

javascript - 如何使用 Stripe Payment Intents 提供账单详细信息以确保 SCA 合规性?

javascript - 输入格式 jQuery

javascript - 有没有什么方法可以在不迭代的情况下从对象数组中创建属性数组?

javascript - 如何使用 Promise 发送对象数组

javascript - 向上滚动时如何重置 scrollTop() div 定位?

javascript - Java 中的 GraalVM JavaScript - 如何识别异步方法

javascript - 无法从 ul 待办事项列表中删除列表项

javascript - 如何规范跨浏览器的 CSS3 过渡结束事件?