动态添加到Python asyncio';事件循环应该执行
我有一个函数download\u all,它遍历一个硬编码的页面列表,按顺序下载所有页面。但是如果我想根据页面的结果动态地添加到列表中,我该怎么做呢?例如,下载第一个页面,解析它,并根据结果将其他页面添加到事件循环中动态添加到Python asyncio';事件循环应该执行,python,asynchronous,coroutine,python-asyncio,Python,Asynchronous,Coroutine,Python Asyncio,我有一个函数download\u all,它遍历一个硬编码的页面列表,按顺序下载所有页面。但是如果我想根据页面的结果动态地添加到列表中,我该怎么做呢?例如,下载第一个页面,解析它,并根据结果将其他页面添加到事件循环中 @asyncio.coroutine def download_all(): first_page = 1 last_page = 100 download_list = [download(page_number) for page_number in r
@asyncio.coroutine
def download_all():
first_page = 1
last_page = 100
download_list = [download(page_number) for page_number in range(first_page, last_page)]
gen = asyncio.wait(download_list)
return gen
if __name__ == '__main__':
loop = asyncio.get_event_loop()
futures = loop.run_until_complete(download_all())
请看一看
它使用
asyncio.JoinableQueue
queue来存储获取任务的URL,但也演示了许多有用的技术。实现这一点的一种方法是使用队列
#!/usr/bin/python3
import asyncio
try:
# python 3.4
from asyncio import JoinableQueue as Queue
except:
# python 3.5
from asyncio import Queue
@asyncio.coroutine
def do_work(task_name, work_queue):
while not work_queue.empty():
queue_item = work_queue.get_nowait()
# simulate condition where task is added dynamically
if queue_item % 2 != 0:
work_queue.put_nowait(2)
print('Added additional item to queue')
print('{0} got item: {1}'.format(task_name, queue_item))
yield from asyncio.sleep(queue_item)
print('{0} finished processing item: {1}'.format(task_name, queue_item))
if __name__ == '__main__':
queue = Queue()
# Load initial jobs into queue
[queue.put_nowait(x) for x in range(1, 6)]
# use 3 workers to consume tasks
taskers = [
do_work('task1', queue),
do_work('task2', queue),
do_work('task3', queue)
]
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.wait(taskers))
loop.close()
使用来自asyncio的队列,可以确保工作的“单元”与最初提供给asyncio事件循环的任务/未来是分开的。基本上,这允许在一定条件下增加额外的“单位”工作量
请注意,在上面的示例中,偶数编号的任务是终端任务,因此在这种情况下不会添加额外的任务。这最终会导致所有任务的完成,但在您的情况下,您可以轻松地使用另一个条件来确定是否将另一项添加到队列中
输出:
Added additional item to queue
task2 got item: 1
task1 got item: 2
Added additional item to queue
task3 got item: 3
task2 finished processing item: 1
task2 got item: 4
task1 finished processing item: 2
Added additional item to queue
task1 got item: 5
task3 finished processing item: 3
task3 got item: 2
task3 finished processing item: 2
task3 got item: 2
task2 finished processing item: 4
task2 got item: 2
task1 finished processing item: 5
task3 finished processing item: 2
task2 finished processing item: 2
如果你在这里给出一个实际的例子,然后引用这个例子,那就太好了。这个例子比通常的例子要大。我怀疑把它推到这里是否值得。