代码之家  ›  专栏  ›  技术社区  ›  barciewicz

如何将更复杂的逻辑融入到异步期货清单理解中

  •  0
  • barciewicz  · 技术社区  · 6 年前

    我已经编写了一个从Strava的公共API下载活动ID的函数。

    函数将迭代API页面,收集ID,并在从标识为最后一个页面的页面收集ID后停止:

     import requests
    
     def get_activity_ids(): 
                """Returns a list of activity ids for the token owner"""            
                ids = []
                params = {
                    'page': 1,
                    'per_page':200, 
                    'access_token':'1111111',
                } 
                while True:              
                    r = requests.get('https://www.strava.com/api/v3/athlete/activities', params).json()
                    if len(r) == 0:
                        break
                    else:
                        ids += [activity['id'] for activity in r]
                        if len(r) < 200: # if last page
                            break
                    print('PAGE: {}, response length: {}'.format(params['page'], len(r)))
                    params['page'] += 1
                return ids
    

    我现在想把这个函数转换成异步函数。 到目前为止,我得到了:

    import asyncio
    import concurrent.futures
    import requests
    
    def get_ids():
        ids = []
        async def main():
            with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
                loop = asyncio.get_event_loop()
                futures = [
                    loop.run_in_executor(
                        executor,
                        requests.get,
                        'https://www.strava.com/api/v3/athlete/activities?page={page}&per_page=200&access_token=111111111'.format(page=page)
                    )
                    for page in range(1,4)
                ]
                for response in await asyncio.gather(*futures):
                    for activity in response.json():
                        ids.append(activity['id'])
                    pass
        loop = asyncio.get_event_loop()
        loop.run_until_complete(main())
        return ids
    

    但我不知道如何将上一个函数(即 while True 阻止)进入这个。

    所以我需要以某种方式替换 for i in range(1,4) 有这样的逻辑。

    有人知道怎么做吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   user2357112    6 年前

    您试图并行化不能并行运行的操作。每个请求都需要等待上一个请求完成,然后才能知道是否应该发生下一个请求。这是固有的顺序。

    如果您可以请求不存在的页面,那么您可能会同时提交有限数量的请求,在以前的请求完成时发出更多的请求,并在您发现已到达末尾时停止。这并不像清单理解和 gather 但是。