2

我正在尝试开发一个代理,作为使用 0MQ 的一些工作人员和客户端之间通信的代理。这个任务在没有 Promise 的情况下相对简单,但由于我对 Promise 的使用缺乏经验,我无法理解如何在这个示例中实现 Promise。

经纪人代码:

//Broker that serves as proxy for workers and clients
var zmq = require('zmq');
var frontend = zmq.socket('router');
var backend = zmq.socket('router');
var Q = require('q');

frontend.bindSync('tcp://*:8001');
backend.bindSync('tcp://*:8002');

var frontendOn = Q.nbind(frontend.on, frontend);
var backendOn = Q.nbind(backend.on, backend);

var requestFrontend = frontendOn('message').then(function(){
console.log("Message received");
});
var requestBackend = backendOn('message').then(responseBackend);

...

客户端代码:

//Client program that communicates with broker

var zmq = require('zmq')
var requester = zmq.socket('req');
var Q = require('q');

var arguments = process.argv.splice(2);

//Connect with broker
requester.connect(arguments[0]); 

console.log("Connected successfully to broker");

//Send message to broker
requester.send(arguments[1]);   

console.log("Message sent to broker");

...

客户端连接到代理,发送消息但代理不处理消息。关于我做错了什么的任何想法?任何帮助,将不胜感激。

4

1 回答 1

3

我没有使用过 ZeroMQ,但从文档中我认为这on似乎是一种事件订阅机制,而不是接受回调的 NodeJS 风格的异步操作。它可能会触发不止一次,对吧?

如果是这样,你为什么要使用 Promise?对于这种特殊情况,它们似乎是错误的抽象。

Promise 表示完成或失败一次的操作,而不是异步的值流。

即使

var requestFrontend = frontendOn('message').then(function(){
  console.log("Message received");
});

工作,它对你没有任何好处,因为then只会被调用一次。
我想这不是你想要的。

如果您正在寻找一种过滤、映射、合并或限制异步序列的方法,您可以查看RxJS正是这样做的(它也与 Promise 交互)。但是承诺不应该,也不能用来替代触发多次的事件。


另一方面,如果消息确实只出现一次,我同意最好使用承诺将其抽象出来。但是,nfbind或者nbind不会在这里工作,因为它们需要function(err, result)-style 回调,而你有function(result).

这是我建议您改用的:

function promiseOneMessage(queue) {
  var deferred = Q.defer();

  queue.on('message', deferred.resolve);
  queue.on('error', deferred.reject);

  return deferred.promise;
}

var requestFrontend = promiseOneMessage(frontend)
  .then(function (message) {
    console.log("Message received", message);
  })
  .done();

var requestBackend = promiseOneMessage(backend)
  .then(responseBackend)
  .done();
于 2014-01-04T22:17:21.330 回答