摘要:的方法在中,提供了方法來拋出異常。總結關于生成器的異常處理,這里來進行一下總結。最近在研究使用實現半協程,而這個過程中,對異常的處理,是非常重要的。但是的運行方式決定了異常處理比較難以理解。
PHP 中的異常處理本文是我在研究 PHP 異步編程時的總結。對于相當多的 PHPer 來說,可能都不知道 Generator,或者對 Generaotr 的流程不是很熟悉。因為 Generator 使得程序不再是順序的。鑒于本人的水平有限,如果有不同意見,還望指點一二,不勝感激!
從 PHP 5 開始,PHP 為我們提供了 try catch 來進行異常處理。當我們使用 catch 將異常捕獲,那么一場后續的代碼就會執行。我們看看下面的例子。
try { throw new Exception("e"); } catch (Exception $e) { echo $e->getMessage(); // output: e } echo 2; // output: 2
如果我們沒有將異常捕獲,那么后面的代碼就不會執行了。
throw new Exception("e"); // throw an exception echo 2; // not executeGenerator 的 throw 方法
在 PHP 中,Generator 提供了 throw 方法來拋出異常。用法和普通的異常一樣,只不過把 throw 關鍵字改成了方法調用。
function gen() { yield 0; yield 1; yield 2; yield 3; } $gen = gen(); $gen->throw(new Exception("e")); // throw an exception var_dump($gen->valid()); // output: false echo 2; // not execute
同樣的,我們可以這個異常捕獲,通過 try catch 來進行。
try { $gen->throw(new Exception("e")); } catch (Exception $e) { echo $e->getMessage(); // output: e } var_dump($gen->valid()); // output: false echo 2; // output: 2
我們可以看到,當我們使用 throw 拋出異常后,當前的生成器的 valid 變成了 false。但是考慮下面一種情況,當我們在外面調用 throw 方法后,在生成器函數中捕獲異常,會發生什么呢?我們來看下面的例子。
function gen() { yield 0; try { yield; } catch (Exception $e) { echo $e->getMessage(); // output: e } yield 2; yield 3; } $gen = gen(); $gen->next(); // reach the point of catching exception $gen->throw(new Exception("e")); var_dump($gen->valid()); // output: true echo 2; // output: 2
當我們在生成器函數捕獲來自 throw 方法拋出的異常后,生成器依然是 valid 的。但是如果像剛才一樣只是在調用 throw 方法,那么生成器就結束了。
在生成器函數中拋出異常function gen() { yield 0; throw new Exception("e"); yield 2; yield 3; } $gen = gen(); $gen->next(); $gen->current(); // throw an exception var_dump($gen->valid()); // output: false echo 2; // not execute
之前我們看到的是調用 throw 方法來拋出異常。那么在生成器函數中,拋出一個異常而沒有在生成器函數中捕獲,結果也都是一樣的。同樣的,如果在生成器函數中捕獲了異常,那么就和之前的例子一樣了。
在理解了上面的例子之后,我們就要考慮一下,如果有嵌套的生成器,會發生什么了。
嵌套生成器當我們在一個生成器函數中,yield 了另外一個生成器函數之后,就會變成嵌套生成器。我們來看下面的例子。
function subGen() { yield 1; throw new Exception("e"); yield 4; } function gen() { yield 0; yield subGen(); yield 2; yield 3; } $gen = gen(); $gen->next(); $gen->current()->next(); // throw an exception echo 2; // not execute
對于嵌套的生成器來說,如果子生成器中拋出了異常,那么在沒有捕獲這個異常的情況下,會一級一級向上拋出,直到結束。
剛才我們嘗試了,在拋出異常之后,valid 的返回值變成了 false。那么在嵌套生成器中,是不是也是這樣呢?我們把異常捕獲,使程序能夠繼續執行下去,來看下面這個例子。
function subGen() { yield 1; throw new Exception("e"); yield 4; } function gen() { yield 0; yield subGen(); yield 2; yield 3; } $gen = gen(); $gen->next(); try { $gen->current()->next(); } catch (Exceprion $e) { echo $e->getMessage(); //output: e } var_dump($gen->valid()); // output: true echo 2; // output: 2
所以,當子生成器拋出異常后在迭代的過程中被正常地捕獲,那么,父生成器便不會受到影響,valid 的返回值依然是 true。
總結關于生成器的異常處理,這里來進行一下總結。
在生成器中拋出一個異常,或者使用 throw 方法拋出一個異常,那么,生成器的迭代便會結束,valid 變成 false;
在生成器中拋出一個異常,迭代過程中對異常進行捕獲,生成器的迭代依然會結束,valid 依然會變成 false;
在生成器中拋出一個異常,在生成器中將其捕獲處理,生成器的迭代不會結束,valid 會返回 true;
在嵌套的生成器中,如果子生成器拋出了異常,只會對子生成器產生影響,不會對父生成器產生影響。
后記yield 為我們提供了使用 PHP 實現半協程的工具。最近在研究使用 yield 實現半協程,而這個過程中,對異常的處理,是非常重要的。但是 yield 的運行方式決定了異常處理比較難以理解。于是我花了幾天的時間,嘗試了各種可能,得出來的這些結論。當然由于本人水平有限,如有錯誤,還望指點一二,不勝感激。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/25663.html
摘要:編寫代碼的開發人員必須負責代碼的生產部署。構建和部署鏈需要重大更改,以便為微服務環境提供正確的關注點分離。該對象會在之后的時被這時的回調函數會被調用,并輸出。微服務部署及集成部署微服務時有一個原則一個容器中只放一個服務,可以使用編 前幾天在微信群做的一次分享,整理出來分享給大家,相關代碼請戳 https://github.com/Carrotzpc/docker_web_app sho...
摘要:編寫代碼的開發人員必須負責代碼的生產部署。構建和部署鏈需要重大更改,以便為微服務環境提供正確的關注點分離。該對象會在之后的時被這時的回調函數會被調用,并輸出。微服務部署及集成部署微服務時有一個原則一個容器中只放一個服務,可以使用編 前幾天在微信群做的一次分享,整理出來分享給大家,相關代碼請戳 https://github.com/Carrotzpc/docker_web_app sho...
摘要:以下展示它是如何工作的函數使用構造函數創建一個新的對象,并立即將其返回給調用者。在傳遞給構造函數的函數中,我們確保傳遞給,這是一個特殊的回調函數。 本系列文章為《Node.js Design Patterns Second Edition》的原文翻譯和讀書筆記,在GitHub連載更新,同步翻譯版鏈接。 歡迎關注我的專欄,之后的博文將在專欄同步: Encounter的掘金專欄 知乎專欄...
摘要:每個任務必須顯式地掛起自己,在任務切換發生時給予它完全的控制。在這些嘗試中,數據經常在任務之間共享。但由于明確的暫停,幾乎沒有風險。 翻譯自 github 概述 什么是generators? 我們可以把generators理解成一段可以暫停并重新開始執行的函數 function* genFunc() { // (A) console.log(First); yi...
摘要:異步編程解決方案事件發布訂閱模式訂閱,發布事件監聽是一種高階函數的應用,通過事件可以把內部數據傳遞給外部的調用者,編程者可以不用關心組件內部如何執行,只需關注在需要的事件點上即可。 異步編程難點 異常處理 在處理異常時經常用try/catch/final語句塊進行異常捕獲,但是這種異常捕獲對異步編程并不是用 function async(callback) { process....
閱讀 1261·2021-09-02 13:36
閱讀 2714·2019-08-30 15:44
閱讀 2972·2019-08-29 15:04
閱讀 3193·2019-08-26 13:40
閱讀 3643·2019-08-26 13:37
閱讀 1172·2019-08-26 12:22
閱讀 1003·2019-08-26 11:36
閱讀 1214·2019-08-26 10:41