理解Twisted的Deferred机制(二)使用inlineCallbacks实现类同步语法

上文提到使用deferred对象很容易陷入回调地狱中,好在python提供yield生成器语法,可以很容易就包装一套更加友好的

异步编程API。就如同ES6提供的Promise等。


目前在Twisted中提供了一个inlineCallbacks装饰器。能简化多Deferred操作,先上代码:

from twisted.internet.defer  import  inlineCallbacks, Deferred, returnValue
from twisted.python.failure  import  Failure

from twisted.internet import reactor, defer

 
def loadRemoteData(callback):
    import time
    time.sleep(1)
    callback(1)

def loadRemoteData2(callback):
    import time
    time.sleep(1)
    callback(2)

@defer.inlineCallbacks
def getRemoteData():
    d1 = defer.Deferred()
    reactor.callInThread(loadRemoteData,d1.callback)
    r1 = yield d1

    d2 = defer.Deferred()
    reactor.callInThread(loadRemoteData2,d2.callback)
    r2 = yield d2

    returnValue(r1+r2)

def getResult(v):
    print "result=",v
if __name__ == '__main__':
    d=getRemoteData()
    d.addCallback(getResult)

    reactor.callLater(4, reactor.stop); 
    reactor.run()

上例中涉及了两个Deferred对象,使用inlineCallbacks装饰器和yield语法,可以用类同步的语法来进行异步编程。


首先说一下Deferred完成是怎么回事,一个Deferred就相对于一个延迟任务的封装。当调用Deferred的callback或errback时,就代表

该异步任务已完成,而callback方法传入的参数就是Defered的结果。

上例中在r1=yield d1中会暂停,inlinecallbacks装饰器实际上就是调用yield的next来获取结果的,等d1 deferred完成后再继续进行下一步操作。

因此我们就实现了类同步语法来进行异步编程的目的,而不必使用嵌套回调等。


最后再通过returnValue(r1+r2)将计算结果返回。如果在py3中,则可以直接return r1+r2




 

你可能感兴趣的:(twisted,Python)