事實上Deferred的確就像是一連串的動做,用callback的形式被串在一塊兒,我們用deferred或許能夠這樣寫react
d.addCallback(洗菜)
d.addCallback(切菜)
d.addCallback(放到鍋中)
d.addCallback(加鹽)api
若是隻是這樣看起來就像是單純的責任鍊,作完一件事情把結果往下丟,可是,若是發生例外呢?事件
def 切菜(data):
raise 切到手指('Ouch!')同步
若是隻是單純的責任鍊,會從最初呼叫它的地方丟出來,若是隻是通常的單thread程式這樣跑下來,其實加上一個try except就能夠抓到了,但
是twisted是處理非同步的事件,全部事件都是由reactor.run()來驅動的,例外若是從run裡被丟出來,除了整個程序就中止了以外,我
們想去處理那些例外也就辦不到,所以它的error callback機制,目的就是在讓使用者也能夠處理到錯誤thread
像這樣
d.addCallback(切菜)
d.addErrback(處理切菜錯誤)程序
除此以外他還有不少特異功能,有用平鋪直述的寫法所沒有的好處,我們這樣假設,炒菜是一件須要卡住整個線程執行三分鐘的事情,若是用直述的寫法call
加鹽(ret)
炒菜(ret) # 我們會在這裡等三分鐘error
這對於非同步的處理來說無疑的是一大體命傷,後面還一堆事件處理,卻有個笨蛋為了炒菜佔了你們三分鐘時間,在這三分鐘裡其它事件都沒辦法被處理,像這個
時候怎麼辦? 用Deferred的好處就來了callback
def _炒菜(data):
# 花三分鐘炒菜rbac
def 炒菜(data):
return threads.deferredInThread(_炒菜) # api名稱我不確定 不過應該差不了多少
那對deferred的操做會像這樣
d.addCallback(加鹽)
d.addCallback(炒菜)
d.addCallback(上菜)
看到了沒有,很奇怪不是嗎? 我們的炒菜callback竟然也回傳一個deferred物件,twisted到底會怎麼作? 把deferred物件
丟給上菜嗎? 答案是,twisted會等那個deferred物件callback,然後把回傳值丟給上菜,很奇妙不是嗎? 他會幫你把
deferred串接起來,所以deferred不是多此一舉的東西,而是帶來非同步程式很是大彈性的美麗設計,當你越瞭解deferred,你會覺得
這個設計真的很棒
以上