I am trying to understand Python asyncio module. It seems to be much more complicated than similar functionalities in other languages.
Here is an excerpt from documentation:
Calling a coroutine does not start its code running – it is just a generator, and the coroutine object returned by the call is really a generator object, which doesn’t do anything until you iterate over it. In the case of a coroutine object, there are two basic ways to start it running: call yield from coroutine from another coroutine (assuming the other coroutine is already running!), or schedule its execution using the async() function or the BaseEventLoop.create_task() method.
Coroutines (and tasks) can only run when the event loop is running.
Does it mean that it is impossible to achieve similar execution flow like here with Hack?
function main() : void
{
$info = Vector {};
for ($i = 0; $i < 5; $i++) {
$info[] = genInfo($i);
}
echo '[main] Calling Async Function'."\n";
$asyncCall = GenVectorWaitHandle::create($info);
echo '[main] Doing whatever...'."\n";
echo '[main] Time To Request Async Return Information'."\n";
$output = $asyncCall->join();
// Output Vector Data
foreach ($output as $key => $value)
{
echo '['.$key.'] => '.$value."\n";
}
}
async function genInfo(int $id): Awaitable<String> {
echo '[genInfo] Generating '.$id."\n";
$tmp = [];
$tmp['id'] = $id;
$tmp['start'] = date('H:i:s');
//do some heavy working.
await SleepWaitHandle::create(mt_rand(1000000,15*1000000));
$tmp['end'] = date('H:i:s');
echo "[genInfo] Completed $id\n";
return json_encode($tmp);
}
main();
/*
* This is a modified example from http://kernelcurry.com/blog/asynchronous-hack/
*/
//Output
[genInfo] Generating 0
[genInfo] Generating 1
[genInfo] Generating 2
[genInfo] Generating 3
[genInfo] Generating 4
[main] Calling Async Function
[main] Doing whatever...
[main] Time To Request Async Return Information
[genInfo] Completed 0
[genInfo] Completed 3
[genInfo] Completed 2
[genInfo] Completed 1
[genInfo] Completed 4
[0] => {"id":0,"start":"19:46:00","end":"19:46:03"}
[1] => {"id":1,"start":"19:46:00","end":"19:46:08"}
[2] => {"id":2,"start":"19:46:00","end":"19:46:05"}
[3] => {"id":3,"start":"19:46:00","end":"19:46:04"}
[4] => {"id":4,"start":"19:46:00","end":"19:46:08"}
As you can see, genInfo()
execution starts immediately after call and yields on the await statement. I think that such execution flow is much more natural then this one with Python.
Is there any way to achieve the same in Python?
I tried to iterate coroutines generators one time (in order to allow them to execute and approach first yield) before passing them to loop.run_until_complete()
, but without success.