代码之家  ›  专栏  ›  技术社区  ›  MT-FreeHK

等待多个aiohttp请求导致“会话已关闭”错误

  •  0
  • MT-FreeHK  · 技术社区  · 8 年前

    我正在编写一个帮助类,用于以异步方式处理多个url请求。代码如下。

    class urlAsyncClient(object):
        def  __init__(self, url_arr):
            self.url_arr = url_arr
    
        async def async_worker(self):
            result = await self.__run()
            return result
    
        async def __run(self):
            pending_req = []
            async with aiohttp.ClientSession() as session:
                for url in self.url_arr:
                    r = self.__fetch(session, url)
                    pending_req.append(r)
            #Awaiting the results altogether instead of one by one
            result = await asyncio.wait(pending_req)
            return result
    
        @staticmethod
        async def __fetch(session, url):
            async with session.get(url) as response: #ERROR here
                status_code = response.status
                if status_code == 200:
                    return await response.json()
                else:
                    result = await response.text()
                    print('Error ' + str(response.status_code) + ': ' + result)
                    return {"error": result}
    

    一个接一个地等待结果在异步中似乎毫无意义。我把他们排成一排,一起等 await asyncio.wait(pending_req) .

    但似乎这不是正确的方法,因为我得到以下错误

    使用会话获取异步。获取(url)作为响应:运行时错误:会话已关闭

    我能知道正确的方法吗?谢谢。

    1 回复  |  直到 8 年前
        1
  •  1
  •   Kr.98    7 年前

    因为会话在您等待之前已关闭

      async with aiohttp.ClientSession() as session:
            for url in self.url_arr:
                r = self.__fetch(session, url)
                pending_req.append(r)
      #session closed hear
    

    您可以将会话作为参数 __run ,就像这样

    async def async_worker(self):
        async with aiohttp.ClientSession() as session:
            result = await self.__run(session)
            return result
        # session will close hear
    
    async def __run(self, session):
        pending_req = []
        for url in self.url_arr:
            r = self.__fetch(session, url)
            pending_req.append(r)
        #Awaiting the results altogether instead of one by one
        result = await asyncio.wait(pending_req)
        return result