asyncio是python中的异步网络库,专门启动事件循环来运行协程的。在早期python还不支持原生协程的时候,tornado是通过yield来模拟协程,并且自己实现了一套事件循环。所以如果你希望异步处理请求的话,一般你会打上tornado.gen.coroutine这么个装饰器。但是自从官方支持了原生协程,并且推出了asyncio这个库,tornado貌似在4.3之后就不再使用自己的那一套事件循环了,底层的调度直接使用的asyncio。而且在定义get函数的时候,直接通过async def定义就可以了,所以tornado现在是支持python原生的协程的,比如你定义一个协程函数,用tornado的事件循环也是可以运行的。
from tornado.ioloop import IOLoop
async def foo():
print(123)
IOLoop.current().run_sync(foo) # 123
个人觉得真要对比的话,asyncio和twisted应该更具有可比性。twisted编程容易陷入回调地狱当中,而asyncio最大的特点就是可以让你以同步的方式编写异步的代码,但是效率上讲它不一定有twisted快。
关于Django中能否引入asyncio,3.x版本我不清楚,但是2.x想引入asyncio,需要依赖线程池。因为Django的在处理请求的时候是同步的,你无法把一个同步的请求异步化,除非你把Django从底层重新实现一遍。而tornado之所以支持,是因为它把请求封装成了一个协程,然后事件循环去调度。
再比如requests
import requests
async def foo1(url):
requests.get(url)
async def foo2(url):
requests.get(url)
你在运行的时候,起不到任何的异步效果。因为requests请求数据本身是同步的,你写在协程里面它还是同步的,不可能说在执行foo1的时候阻塞了、会自动切换到foo2,这个时候你需要使用aiohttp。因此你在Django2.x版本中想只使用asyncio是几乎不可能的,你肯定要通过附加线程池的技术才能得到异步的效果。
所以python中的协程比较恶心人的地方就在于,你想用都不知道该在什么用。基本上都使用第三方的,因为真正想实现异步的话,你需要从底层重新实现一些协议什么的。