2014-09-25 2 views
2

В jQuery $.when(promise1, promise2...) используется как главное обещание, чтобы представить общее состояние его детей. Затем мы можем приложить .done(callback) к обещанию $.when, так что, когда будет завершено выполнение ВСЕ promise1, promise2..., будет выполнено callback.

В Python (Торнадо) Future действует аналогично обещанию в javascript, а fetch() в AsyncHTTPClient возвращает будущее.

В следующем коде у меня есть список фьючерсов

from tornado.httpclient import AsyncHTTPClient 

httpclient = AsyncHTTPClient() 
futures = [ 
    httpclient.fetch("http://google.com") 
    httpclient.fetch("http://example.com") 
    httpclient.fetch("http://example.org") 
] 

def all_futures_done_callback(): 
    ... 

Как выполнить all_futures_done_callback когда все фьючерсы закончили?

ответ

1

Мне кажется, что вам нужно будет создать эту функциональность самостоятельно. Это проверялось, но что-то подобное, кажется, как он должен работать:

class FutureCollection(Future): 
    def __init__(self, *args, **kwargs): 
     super(FutureCollection, self).__init__(*args, **kwargs) 
     self._waiting_for = [] 

    def _check_all_done_and_resolve(self, future): 
     if all(f.done() for f in self._waiting_for): 
      # Maybe check for exceptions a. la. 
      # http://tornado.readthedocs.org/en/latest/_modules/tornado/concurrent.html#chain_future 
      self.set_result(None) # Not sure what the result should be. 

    def add_future(self, future): 
     self._waiting_for.append(future) 
     future.add_done_callback(self._check_all_done_and_resolve) 

    @property 
    def futures(self): 
     # Read-only access to the futures that have been added. 
     return iter(self._waiting_for) 
+0

Ответ Бена краток, но ваш более расширяемый, поэтому я принял ваш ответ. Спасибо вам обоим! –

+0

@MKYung - Если честно, я никогда не использовал торнадо раньше ;-). Недавно я немного пообщался с обещаниями в своем опыте JS, поэтому решил, что попробую на другом языке. – mgilson

2

В сопрограмме это легко ждать несколько фьючерсов; просто дать им все в виде списка:

@gen.coroutine 
def f(): 
    futures = [ 
     httpclient.fetch("http://google.com") 
     httpclient.fetch("http://example.com") 
     httpclient.fetch("http://example.org") 
    ] 
    responses = yield futures 

Чтобы сделать это с помощью функции обратного вызова вместо сопрограмм вам нужно что-то вроде ответа mgilson в.