2017-06-03 53 views
7

Mam 2 funkcje: Pierwszy, def_a, to funkcja asynchroniczna, a drugi jest def_b który jest regularny funkcję i nazywa z wynikiem def_a jako zwrotnego z funkcją add_done_callback.pyton asyncio add_done_callback z asynchroniczny def

Mój kod wygląda następująco:

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() 

I to działa idealnie.

Problem zaczął się, gdy druga funkcja, def_b, stała się asynchroniczna. Teraz wygląda to tak:

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

Ale teraz nie mogę dostarczyć go do funkcji add_done_callback, ponieważ nie jest to regularne funkcji.

Moje pytanie jest-jest to możliwe iw jaki sposób mogę zapewnić def_b do funkcji add_done_callback jeśli def_b jest asynchroniczne?

Odpowiedz

10

add_done_callback jest uważany za interfejs "niskiego poziomu". Podczas pracy z współprogram można chain them na wiele sposobów, na przykład:

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() 

Pamiętaj add_done_callback będzie nadal nazywają zwrotnego jeśli przyszłość zgłasza wyjątek (ale nazywając result.result() to podniesie).

+0

dziękuję za dzielenie się, z ciekawości, co jest zaletą korzystania zapewnić przyszłość nad użyciem poczekać my_coro ciągu my_callback – laycat

+1

'ensure_future (coro)' tylko kolejki 'Coro()' dla późniejszego wykonania i nie od razu rozpocząć 'Coro() '. – Udi