理解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




 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值