我有一些基于Pika(0.10.0)提供的异步示例使用者的Python 3.51代码,用于与RabbitMQ(3.6.2)进行通信(http://pika.readthedocs.io/en/latest/examples/asynchronous_consumer_example.html)
目前,队列创建需要一个绑定队列的回调。绑定队列也需要一个成功调用的回调。这已经是我想用某种瀑布流控制替换嵌套回调的东西,通常是在使用像javascript promises这样的东西时。
此外,我有一个场景,其中单个消息可以导致创建多个队列,并且我想在创建所有队列后确认消息。这将再次适用于某种流控制,一旦所有队列创建序列并行完成,就会调用一个函数。
现在我通过混合嵌套函数和闭包来实现这一目标。这有效,但如果可能的话,流量控制的东西会更清晰。
我如何使用Python中的流控制实现这一点?以下是我当前代码的简化版本。
def on_message(self, unused_channel, basic_deliver, properties, body):
routing_key_components = basic_deliver.routing_key.split('.')
queue_counter = len(routing_key_components) - 2
def queues_setup_complete():
nonlocal queue_counter
queue_counter -= 1
if queue_counter == 0:
self._channel.basic_publish('bar_ex', basic_deliver.routing_key, body, properties)
self.acknowledge_message(basic_deliver.delivery_tag)
for i in range(2, len(routing_key_components)):
sub_key = routing_key_components[i]
routing_pattern = 'foo.%s' % sub_key
queue_name = 'foo_%s' % sub_key
exchange_name = 'bar_ex' % sub_key
self._channel.queue_declare(self.on_foo_queue_declareok(routing_pattern,
exchange_name,
queues_setup_complete),
queue_name)
def on_foo_queue_declareok(self, routing_pattern,
exchange_name, queues_setup_complete):
# nested function with closure returned to allow passing additional parameters to the callback function
def queue_declared(method_frame):
self._channel.queue_bind(self.on_foo_queue_bindok(queues_setup_complete),
method_frame.method.queue,
exchange_name, routing_pattern)
return queue_declared
def on_foo_queue_bindok(self, queues_setup_complete):
# nested function with closure returned to allow passing the 'queue_setup_completed' function
# to the callback.
def foo_bound(unused_frame):
queues_setup_complete()
return foo_bound