twisted中的延迟(deferred)(二)

单个回调 我们在上一节已经说过了

​​​​​​twisted中的延迟(deferred)(一)_zhangdell的专栏-CSDN博客

1:deffered 延迟链

from twisted.internet import defer
def myfun1(s):
    print("myfun1 s=",s)
    return "myfun1"
def myfun2(s):
    print("myfun2 s=",s)
    return "myfun2"
 
d = defer.Deferred()
d.addCallback(myfun1)
d.addCallback(myfun2)
d.callback("hello start")
myfun1 s= hello start
myfun2 s= myfun1

        将多个回调加入延迟链中,第一个回调函数是用d.callback("hello start")触发的,而且要注意的是必须要有一个参数才能调用,因为callback是需要参数的,否则d.callback() 会报错(TypeError: callback() missing 1 required positional argument: 'result')。callback的参数是传给第一个回调函数的,所以第一个回调函数必须带一个参数。

        第二个回调使用第一个回调的结果当做参数来执行计算,即使第一个回调函数没有返回值,第二个回调函数也必须带参数,这是这个形参的值是None罢了

myfun1 s= hello start
myfun2 s= None

        也就是说myfunc1和myfunc2等设置的回调函数必须是要有一个参数的,即使myfun1没有任何返回值,myfunc2也必须是带参数的,否则 builtins.TypeError: myfun2() takes 0 positional arguments but 1 was given。

如果回调的过程中出现异常,将绕过回调链,切换到errback链。

def su_cb1(num):
    num = num + 1
    print("su_cb1=",num)
    return num

def su_cb2(num):
    num = num + 1
    print("su_cb2=",num)
    return num

def su_cb3(num):
    num = num + 1
    print("su_cb3=",num)
    return num

def err_cb1(fail):
    num = int(str(fail.value)) + 1
    print("err_cb1",fail.type.__name__,fail.value,num)
    if num < 10:
        raise ValueError(num)
    else:
        return num

def err_cb2(fail):
    num = int(str(fail.value)) + 1
    print("err_cb2",fail.type.__name__,fail.value,num)
    if num < 10:
        raise ValueError(num)
    else:
        return num
    
def err_cb3(fail):
    num = int(str(fail.value)) + 1
    print("err_cb3",fail.type.__name__,fail.value,num)
    if num < 10:
        raise ValueError(num)
    else:
        return num

curnum = 8
d = defer.Deferred()
d.addCallback(su_cb1)
d.addCallback(su_cb2)
d.addErrback(err_cb1)
d.addErrback(err_cb2)
d.addCallback(su_cb3)

if curnum < 10:
    d.errback(ValueError(curnum))
else:
    d.callback(curnum)

  

调整curnum的值,以及callback errback的顺序 能模拟不同的情况。总之,正如上图那样,callback和errback 是可以相互切换的。如本例err_cb1--->err_cb2--->su_cb3,在回调err_cb2 num=10,正常返回,接着应该调用正常的callback,但是只回调err_cb2之后注册的callback连,也就是su_cb3,su_cb1和su_cb2由于是在err_cb2之前注册的,所以不在回调之列

2:DeferredList

        前边使用defer都是使用后不等待数据返回继续执行其他的操作,待数据就绪后再通过回调函数来处理数据。这些操作都是等待单一数据,但有时需要等待多份数据全部都返回后才能继续操作,这个时候就该DeferredList出场了。

deferrlist: 其所需等待的defer对象列表
fireOnOneCallback:

True:list列表中任一defer对象callback后,List就回调callback(只要有一个deferred调用了callback,list就会立即调用它的callback)

False:等待所有defer执行完。


fireOnOneErrback:deferrlist列表中任一defer对象errback后,如果deferr对象未指定errback,DeferredList就回调errback(只要有一个deferred调用了errback,list就会调用它的errback)

consumeErrors:deferrlist列表中任一defer对象执行过程中发生错误后,如果deferr对象未指定errback, DeferredList就回调errback

consumeErrors参数传递一个True不会影响fireOnOneCallbackfireOnOneErrback的行为 

from twisted.internet import defer

def myfun1(a):
    print("myfun1--->",a)
    return a

def myfun2(b):
    print("myfun2--->",b)
    return b

def myfun3(c):
    print("myfun3--->",c)
    return c

def err1(b):
    print("err1--->",b)
    return b

def err2(b):
    print("err2--->",b)
    return b

def err3(b):
    print("err3--->",b)
    return b

def printResult(result):
    print("printResult--->",result)

def printErr(f):
    print("printErr--->",f)

deferred1 = defer.Deferred()
deferred2 = defer.Deferred()
deferred3 = defer.Deferred()
deferred1.addCallback(myfun1)
deferred1.addErrback(err1)
deferred2.addCallback(myfun2)
deferred2.addErrback(err2)
deferred3.addCallback(myfun3)
deferred3.addErrback(err3)

dl = defer.DeferredList([deferred1, deferred2, deferred3], fireOnOneCallback=False,fireOnOneErrback=False,consumeErrors=False)
dl.addCallback(printResult)
dl.addErrback(printErr)

# deferred1.callback('one')
# deferred2.callback('two')
# deferred3.callback('three')
deferred1.errback(Exception('bang!'))
deferred2.errback(Exception('bang!'))
deferred3.errback(Exception('bang!'))

 fireOnOneCallback=True,fireOnOneErrback=False,consumeErrors=True 和

fireOnOneCallback=False,fireOnOneErrback=False,consumeErrors=True 结果都是如下图

 fireOnOneCallback=False,fireOnOneErrback=True,consumeErrors=True

先看 fireOnOneErrback,如果为True 当有错误时就执行list的errback,如果为False,不管fireOnOneCallback是True 还是False,最终都会执行list的callback。

 consumeErrors 为False

 consume为True

 consume为True和False的结果,它不会影响fireOnOneCallback和fireOnOneErrback的结果。

  

Twisted之Deferred(一)_bluespacezero的博客-CSDN博客

Twisted之Deferred(二)_bluespacezero的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值