理解Twisted的Deferred机制(一)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wenxuansoft/article/details/51718525

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回调地狱嚣张,都有方法可以解决。






猜你喜欢

转载自blog.csdn.net/wenxuansoft/article/details/51718525