2017-03-06 54 views
1

在下面的代碼中返回異步值之前是否需要loop.close()如何看待和處理事件循環?

import asyncio 

async def request_url(url): 
    return url 

def fetch_urls(x): 
    loop = asyncio.get_event_loop() 
    return loop.run_until_complete(asyncio.gather(*[request_url(url) for url in x])) 

也就是說,應該fetch_urls是這樣的,而不是?:

def fetch_urls(x): 
    loop = asyncio.get_event_loop() 
    results = loop.run_until_complete(asyncio.gather(*[request_url(url) for url in x])) 
    loop.close() 
    return results 

如果需要loop.close(),那麼如何才能fetch_urls再次在不提高例外叫:RuntimeError: Event loop is closed

A previous post指出關閉循環並開始新循環是一種很好的做法,但它並未指定如何打開新循環?

+0

爲了完整起見,你可以開始通話'ASYNCIO一個新的事件循環。 new_event_loop()'。 – dirn

回答

1

不,異步功能(本例中的request)不應該關閉事件循環。命令loop.run_until_complete 關閉 儘快停止事件循環。

fetch_urls應該是第二個版本 - 也就是說,它將得到一個事件循環,運行事件循環,直到沒有什麼可以做,然後關閉它loop.close()

+0

run_until_complete()**'stop()'**循環,它不**關閉**它。 – Udi

+0

@Udi:謝謝,修正。 –

+0

另請參閱我的答案如下:http://stackoverflow.com/a/42635351/57952 – Udi

2

您也可以保留事件循環活着,並關閉程序結束後,使用不止一次run_until_complete更多:

import asyncio 


async def request_url(url): 
    return url 


def fetch_urls(loop, urls): 
    tasks = [request_url(url) for url in urls] 
    return loop.run_until_complete(asyncio.gather(*tasks, loop=loop)) 


loop = asyncio.get_event_loop() 
try: 
    print(fetch_urls(loop, ['a1', 'a2', 'a3'])) 
    print(fetch_urls(loop, ['b1', 'b2', 'b3'])) 
    print(fetch_urls(loop, ['c1', 'c2', 'c3'])) 
finally: 
    loop.close() 
+0

良好的信息。 +1! –

+0

謝謝,這是一個很好的例子:) – Greg