2015-12-20 6 views
10

Im asynchronen JavaScript kombinieren, ist es einfach, Aufgaben parallel laufen zu lassen und für alle von ihnen warten Promise.all vervollständigen mit:awaitables wie Promise.all

async function bar(i) { 
    console.log('started', i); 
    await delay(1000); 
    console.log('finished', i); 
} 

async function foo() { 
    await Promise.all([bar(1), bar(2)]); 
} 

// This works too: 
async function my_all(promises) { 
    for (let p of promises) await p; 
} 

async function foo() { 
    await my_all([bar(1), bar(2), bar(3)]); 
} 

Ich habe versucht, diese in Python neu zu schreiben:

import asyncio 

async def bar(i): 
    print('started', i) 
    await asyncio.sleep(1) 
    print('finished', i) 

async def aio_all(seq): 
    for f in seq: 
    await f 

async def main(): 
    await aio_all([bar(i) for i in range(10)]) 

loop = asyncio.get_event_loop() 
loop.run_until_complete(main()) 
loop.close() 

Aber es führt meine Aufgaben nacheinander aus.

Was ist der einfachste Weg, um mehrere Anforderungen zu erwarten? Warum funktioniert mein Ansatz nicht?

Antwort

16

Das Äquivalent wäre asyncio.wait mit:

import asyncio 

async def bar(i): 
    print('started', i) 
    await asyncio.sleep(1) 
    print('finished', i) 

async def main(): 
    await asyncio.wait([bar(i) for i in range(10)]) 

loop = asyncio.get_event_loop() 
loop.run_until_complete(main()) 
loop.close() 

Warum funktioniert mein Ansatz der Arbeit?

Denn wenn Sie await jedes Element in seq, können Sie diese Koroutine blockieren. Im Wesentlichen haben Sie synchronen Code als async maskiert. Wenn Sie wirklich wollten zu, könnten Sie Ihre eigene Version von asyncio.wait mit loop.create_task oder asyncio.ensure_future implementieren.

EDIT

Wie Andrew erwähnt, können Sie auch asyncio.gather verwenden.

+4

erwähnen Sie bitte asyncio.gather too –

+0

Ist der Hauptunterschied zwischen 'wait' und' gather', dass 'wait' ein 'timeout'-Argument erlaubt? –