#!/usr/bin/python3
# -*- coding: utf-8 -*-
import asyncio,time
async def asleep(n):
    time.sleep(n)   # blocking method
async def doAsync(n):                        
    print("doAsync{} start...".format(n))
    await asleep(2)                             # case 1    
    #await asyncio.gather(asleep(2))            # case 2
    print("doAsync{} end...".format(n))
    #...                                     
tasks = [doAsync(i) for i in range(1,4)]
tasks = [asyncio.ensure_future(t) for t in tasks]
if __name__ == "__main__":                  
    loop = asyncio.get_event_loop()         
    loop.run_until_complete(asyncio.wait(tasks))
    loop.close()                            
output:
## case 1 output        # No concurrency runs
doAsync1 start...       
(wait 2 seconds)
doAsync1 end...
doAsync2 start...
(wait 2 seconds)
doAsync2 end...
doAsync3 start...
(wait 2 seconds)
doAsync3 end...
## case 2 output        # Concurrency runs
doAsync1 start...
doAsync2 start...
doAsync3 start...
(wait 2*3 seconds)      
doAsync1 end...
doAsync2 end...
doAsync3 end...
case 1:
Although asleep() is also a coroutine,
But the doAsync isn't pending at "await asleep()"
doAsync does not implement concurrency
case 2:
doAsync is concurrent
The question:
- How to explain how it works detail.
- When should I use "await some_work()" and when should I use "await asyncio.gather(some_work)"
 
    