簡體   English   中英

異步函數中的變量不會在while-True循環中重新計算

[英]Variable in Async function not re-evaluated in while-True loop

我做了一個虛擬服務器來測試我的websockets應用程序。 它偵聽subscription消息,然后通過套接字提供有關這些訂閱的信息。

初始化時類的subscriptions屬性為空,並且應當在listen()函數接收訂閱消息時填充。 然而,看起來好像在talk() self.subscriptions永遠不會被附加到,它留在無限的while循環中,永遠不會傳輸消息。

通過在for循環之后添加一行await asyncio.sleep(1)來解決該問題。 但為什么? 每次啟動for循環時,是否應該重新評估self.subscriptions

代碼如下:

class DummyServer:
    def __init__(self):
        self.subscriptions = []

    def start(self):
        return websockets.serve(self.handle, 'localhost', 8765)

    async def handle(self, websocket, path):
        self.ws = websocket
        listen_task = asyncio.ensure_future(self.listen())
        talk_task = asyncio.ensure_future(self.talk())

        done, pending = await asyncio.wait(
            [listen_task, talk_task],
            return_when=asyncio.FIRST_COMPLETED
        )

        for task in pending:
            task.cancel()

    async def listen(self):
        while True:
            try:
                msg = await self.ws.recv()
                msg = json.loads(msg)
                await self.triage(msg)  # handles subscriptions
            except Exception as e:
                await self.close()
                break

    async def talk(self):
        while True:
            for s in self.subscriptions:
                dummy_data = {
                    'product_id': s
                }
                try:
                    await self.send(json.dumps(dummy_data))
                except Exception as e:
                    await self.close()
                    break

            await asyncio.sleep(1)  # without this line, no message is ever sent

在函數開始時, subscriptions為空,並且不評估for body。 因此,您的協程實際上與以下內容相同:

async def talk(self):
    while True:
        pass

while循環不包含“上下文切換點”,這意味着asyncio事件循環基本上掛起,永遠執行阻塞 while循環。

添加await sleep()會打破魔術圈; 甚至await sleep(0)可能有所幫助。

聰明的代碼應該可以將asyncio.Conditionself.subscriptions結合使用,但這個問題超出了原始問題的范圍。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM