Twisted作为Python下的异步网络框架,在异步机制上与Nodejs很相像,但Twisted已经发展了十多年了。
为了简化异步编程,Twisted引入了Deferred延迟对象的概念。
Deferred是Twisted异步框架内部实现的一套callback调用的机制,或者可以说是一种设计模式。我们都知道jQuery也有一套Deferred机制,用来简化异步编程。
Twisted的Deferred差不多也是类似的东东。在本质实现上与Twisted的网络是完全可以独立应用的,你完全可以理解为是一套接口。
具体怎么来理解呢,先上代码:
from twisted.internet.defer import Deferred
from twisted.python.failure import Failure
from twisted.internet import reactor, defer
def loadRemoteData(callback,errback,url):
此处加载url内容
callback('url数据')或<span style="font-family: Arial, Helvetica, sans-serif;">errback(...)</span>
def getRemoteData():
d = defer.Deferred()
reactor.callInThread(loadRemoteData,d.callback,d,errback,"http://www.baidu.com")
return d
def getResult(v):
print "result=",v
if __name__ == '__main__':
d=getRemoteData()
d.addCallback(getResult)
reactor.callLater(4, reactor.stop);
reactor.run()
上述getRemoteData从远程加载一个url的内容,由于涉及网络操作,因此需要采用异步操作,也说是我们从远程加载url数据时不堵塞主线程,因此我们调用
<pre name="code" class="python"> reactor.callInThread(loadRemoteData,d.callback,"http://www.baidu.com")
在另外一线程进行读取,这样就不会堵塞主线程,而getRemoteData则只是返回一个Deferred对象。Deferred对象提供了addCallback和addErrCallback两个方法,用来让你注册回调函数。
由于实现的读取操作是个另外一个线程loadRemoteData进行操作,因此getRemoteData方法是不会堵塞的,而是直接返回的。
那当loadRemoteData加载成功时,就执行Deferred对象的callback方法,如果发生错误就调用Deferred对象的errback方法,这两个方法实际上是告诉
deferred对象要做的事情已经完成,如果是调用callback方法,则deferred对象就会依次执行addCallback添加的callback方法。如果是调用errback方法,则deferred对象就会依次执行addErrback添加的callback方法。
大家可以发现deferred的原理与jquery的Deferred,或es6的promise有些像,其本质就是提供一种机制,或者一种约定的操作模式,让你按统一的形式去进行异步编程而已。
但是大家也可以发现,twisted的deferred机制,也是采用callback 方式,没有jquery Deferred或es6的promise异步编程模式 先进,不能够使用像then().then()这样的链式调用模式。
在实现使用中很容易就会如同javascript一样陷入callback回调地狱中。
好在万能python不可能让这callback回调地狱嚣张,都有方法可以解决。