纖維是暫停和恢復的任意代碼塊的方式。像這樣的例子並不是一個很好的用例,因爲它沒有提供任何比傳統閱讀和處理方式更有利的優勢。
在這個特殊的例子,如果你想變得更好,你會寫一個枚舉風格的界面,所以你可以寫:
words = WordsReader.new("testfile")
words.each do |word|
# ...
end
凡纖維成爲重要的是在編寫異步代碼。例如,在EventMachine環境中,您需要能夠發出異步調用,暫停代碼塊並在收到響應時恢復它。
這結束這樣看:
async_call(argument1, argument2) do |response_1|
if (response_1.ok?)
async_call(argument3, argument4) do |response_2|
if (response_2.ok?)
async_call(argument5, argument6) do |response_3|
if (response_3.ok?)
do_something(response_1, response_2, response_3)
else
panic_and_fail!
end
end
else
panic_and_fail!
end
end
else
panic_and_fail!
end
end
這種類型的嵌套,嵌套和再嵌套調用結構的籠統稱作「回調地獄」,因爲它變得非常難以管理,一旦你的邏輯變得非不重要的。一種扁平化這種結構的方法是使用纖維。一個正確的光纖化等價物是:
begin
response_1 = fiber_call(argument1, argument2)
response_2 = fiber_call(argument3, argument4)
response_3 = fiber_call(argument5, argument6)
do_something(response_1, response_2, response_3)
rescue NotOkay
panic_and_fail!
end
光纖可以利用異常,其中回調類型的代碼不能。如果有效使用,例外可以大量簡化代碼塊,如您在此處所見。而不是在每個響應上測試ok?
,而是預計該調用會拋出NotOkay
類型的異常。
回調不能可靠地拋出異常,因爲在回調發生時,調用的發起者已經超出範圍。這是使用回調進行異步編程的一個基本限制。光纖驅動的代碼維護一個適當的調用棧,它只是暫停和恢復,所以異常通過調用者正確地級聯。
我發現纖維既易於理解又非常難以正確應用。大多數情況下你不需要直接使用它們,你將使用一個庫來代替它們。編寫「光纖感知」代碼與編寫「線程安全」代碼不同。正確的做法可能會非常棘手。
你在17分鐘內寫完了所有內容? –
顯然如此。不知道我正在計時! – tadman
Wow Tadman,我真的很感謝你爲了向我和任何可能遇到它的人解釋這個深度。對此,我真的非常感激。你好,加拿大同胞! :) – Senjai