Twisted 算是最早支持 Linux poll 和 epoll 特性的异步编程框架,其核心是通过 Linux IO 的异步事件机制,通过 Selector 和 Event 的方式通过单线程来同时处理多个 I/O 并发请求;通过 Twisted 我们可以构建支持海量并发请求的服务器;异步请求虽然高效,但难点在于如何优雅的处理回调,于是 Twisted 推出了 Deferred 机制,该机制就是通过事件的方式,通知 Application 某个异步请求执行完毕,可以接着继续执行下一个异步请求了,它的作用非常类似于 Javascript 用来处理异步回调的 Promise 框架。
Twisted 利用 Deferred 对象来处理它的异步回调,使用 Deferred 来封装异步 I/O 事件,当某个异步 I/O 事件有响应以后,便会通过 Deferred 对象中所绑定的回调事件来依次触发其相应的回调方法,不过要注意的是,一个 Deferred 对象通常会依次绑定多个回调方法构成一个回调方法链,回调过程中会依次的挨个调用这些回调方法,同时回调方法本身还可以构建并返回另一个 Deferred 对象,进而进行另一次的异步回调链;
上述便是 Twisted 定义 Deferred 的初衷,但是 Deferred 作为一个独立的框架,它其实是可以独立于 Twisted 使用的,它甚至可以 Defered 一个同步的调用;所以,在开始深入 Defered 以前,要明白 Defered 本身只是处理异步方法回调之后如何优雅的处理其返回结果的一个框架,它本身并不是一个异步执行程序,也不具备任何异步的特性,所以,如果想把一个本身就是同步的代码块作为 callback 注册到 Deferred 对象中,执行过程中,该同步代码块依然是同步代码块,这点和 Javascript 的 Promise 框架是一摸一样的。
callback 是 Deferred 的核心,无论是异步执行成功还是失败,都会都会通过注册到 Deferred 对象中的 callback 方法进行回调处理;Deferred 包含两种回调方式,一种是成功的回调方式,通过 Deferred.callback(result) 触发执行,一种是失败的回调,通过 Deferred.errback(err) 触发执行。
d = getDeferredFromSomewhere() d.addCallback(callback1) # A d.addErrback(errback1) # B d.addCallback(callback2) d.addErrback(errback2)
除了使用上述标准的方式处理异常以外,Deferred 还提供了 callbacks 方法能够注入异常回调方法,比如,
d = getDeferredFromSomewhere() d.addCallbacks(callback1, errback1) # C d.addCallbacks(callback2, errback2)
那么,这两种调用方式有什么异同呢?
区别是,上面的errback1 不仅会处理 getDeferredFromSomewhere() 所抛出的异常,同时会处理 callback1 中所抛出的异常;而如果使用 下面的callbacks 的方式,那么 errback1 则只会处理 getDeferredFromSomewhere() 中所抛出的异常。
详细内容来自这篇文章,写的挺好,学习并记录下:
https://www.shangyang.me/2018/05/05/python-twisted-deferred/