2017-07-17 34 views
1

我正在嘗試爲我正在執行的控制器項目執行一些異步消息傳遞,並且以下函數的目標是將回調返回到appjar app.registerEvent調用,該調用將更新電機控制UI的狀態部分。如何使用asyncio處理閉包

def motorStatusMonitor(loop: aio.AbstractEventLoop, app: aj.appjar.gui, Messenger: cmd.PyCmdMessenger.CmdMessenger)-> Callable: 
    async def getStatus(aFuture): 
     nonlocal Messenger 
     nonlocal app 
     # Ask for the current status of the motor 
     t = await Control.sendCommand(Messenger, "Status") 
     d = {t[1][0]: t[1][1], t[1][2]: t[1][3]} # parse the response 
     def statusChanger(): # need a closure to write to the app when called 
      nonlocal d # use the message from above 
      nonlocal app # use the app passed with motorStatusMonitor 
      app.openTab("Main", "Control") 
      app.openLabelFrame("Status") 
      app.setLabel("motorStatus", f"Motor A: \t\t {get('A', d, '???')}\nMotor B: \t\t {get('B', d, '???')}") # Print the status of the motors to the app 
     aFuture.set_result(statusChanger) 

    future = aio.Future() 
    aio.ensure_future(getStatus(future)) 
    loop.run_until_complete(future) 
    return future.result() 

但是,這不起作用,因爲當我做app.registerEvent(motorStatusMonitor(event_loop, app, Messenger))它只是永遠掛起。

我應該怎樣在這裏實現異步?

全部代碼都在Github

+0

如果沒有實際的代碼顯示你在做什麼,你會如何期待其他人提供幫助? – Ding

+0

我在提問之前不小心打了提交,這是我的錯誤。 – nick5435

+0

你想實現什麼目標?因爲關閉不是問題。至少,你可以重寫你的代碼,而不是使用閉包,而是使用全局的'app'。我並不是說封閉不是正確的方法(即使它在Python中不是很流行)我在說你可能正在討論XY問題https://meta.stackexchange.com/questions/66377/what-is -the-XY-問題。試着擴大你想要達到的目標。 – amirouche

回答

0

此:

loop.run_until_complete(future) 

正在等待未來的完成這不可能發生。

此外,您不能撥打future.result(),而是像await future那樣會返回結果。

+0

所以在我的函數結束時,我需要返回閉包,我只是'返回等待未來',擺脫'loop.run_until_complete'的調用? – nick5435

+0

此外,我不認爲我可以在這裏使用'await',因爲我沒有創建一個coro,所以這個函數特別需要同步。 – nick5435