2017-06-03 6 views
7

Ich habe 2 Funktionen: Die erste, def_a, ist eine asynchrone Funktion und die zweite ist def_b, die eine reguläre Funktion ist, und mit dem Ergebnis der def_a als Rückruf mit der add_done_callback Funktion aufgerufen.Python asyncio add_done_callback mit async def

Mein Code sieht wie folgt aus:

import asyncio 

def def_b(result): 
    next_number = result.result() 
    # some work on the next_number 
    print(next_number + 1) 

async def def_a(number): 
    await some_async_work(number) 
    return number + 1 

loop = asyncio.get_event_loop() 
task = asyncio.ensure_future(def_a(1)) 
task.add_done_callback(def_b) 
response = loop.run_until_complete(task) 
loop.close() 

Und es ist perfekt.

Das Problem begann, als auch die zweite Funktion, def_b, asynchron wurde. Jetzt sieht es wie folgt aus:

async def def_b(result): 
    next_number = result.result() 
    # some asynchronous work on the next_number 
    print(next_number + 1) 

Aber jetzt kann ich es nicht auf die add_done_callback Funktion zur Verfügung stellen, weil es nicht eine reguläre Funktion ist.

Meine Frage ist- Ist es möglich und wie kann ich def_b an die add_done_callback Funktion bereitstellen, wenn def_b asynchron ist?

Antwort

10

add_done_callback wird als "Low-Level" -Schnittstelle betrachtet. Wenn mit Koroutinen arbeiten, können Sie chain them in vielerlei Hinsicht, zum Beispiel:

import asyncio 


async def my_callback(result): 
    print("my_callback got:", result) 
    return "My return value is ignored" 


async def coro(number): 
    await asyncio.sleep(number) 
    return number + 1 


async def add_success_callback(fut, callback): 
    result = await fut 
    await callback(result) 
    return result 


loop = asyncio.get_event_loop() 
task = asyncio.ensure_future(coro(1)) 
task = add_success_callback(task, my_callback) 
response = loop.run_until_complete(task) 
print("response:", response) 
loop.close() 

Haltungsart Geist add_done_callback noch den Rückruf anrufen, wenn Sie Ihre Zukunft eine Ausnahme auslöst (aber result.result() Aufruf wird anheben).

+0

danke für das Teilen, aus Neugier, was ist der Vorteil der Verwendung sicher Zukunft über die Verwendung erwarten my_coro in my_callback – laycat

+1

'sure_future (coro)' nur Warteschlangen 'coro()' für die spätere Ausführung und startet nicht sofort 'coro() '. – Udi