成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Generator 的異常處理

Bmob / 1860人閱讀

摘要:的方法在中,提供了方法來拋出異常。總結(jié)關(guān)于生成器的異常處理,這里來進(jìn)行一下總結(jié)。最近在研究使用實(shí)現(xiàn)半?yún)f(xié)程,而這個過程中,對異常的處理,是非常重要的。但是的運(yùn)行方式?jīng)Q定了異常處理比較難以理解。

本文是我在研究 PHP 異步編程時的總結(jié)。對于相當(dāng)多的 PHPer 來說,可能都不知道 Generator,或者對 Generaotr 的流程不是很熟悉。因?yàn)?Generator 使得程序不再是順序的。鑒于本人的水平有限,如果有不同意見,還望指點(diǎn)一二,不勝感激!

PHP 中的異常處理

從 PHP 5 開始,PHP 為我們提供了 try catch 來進(jìn)行異常處理。當(dāng)我們使用 catch 將異常捕獲,那么一場后續(xù)的代碼就會執(zhí)行。我們看看下面的例子。

try {
    throw new Exception("e");
} catch (Exception $e) {
    echo $e->getMessage(); // output: e
}

echo 2; // output: 2

如果我們沒有將異常捕獲,那么后面的代碼就不會執(zhí)行了。

throw new Exception("e"); // throw an exception

echo 2; // not execute
Generator 的 throw 方法

在 PHP 中,Generator 提供了 throw 方法來拋出異常。用法和普通的異常一樣,只不過把 throw 關(guān)鍵字改成了方法調(diào)用。

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 來進(jìn)行。

try {
    $gen->throw(new Exception("e"));
} catch (Exception $e) {
    echo $e->getMessage(); // output: e
}

var_dump($gen->valid()); // output: false

echo 2; // output: 2

我們可以看到,當(dāng)我們使用 throw 拋出異常后,當(dāng)前的生成器的 valid 變成了 false。但是考慮下面一種情況,當(dāng)我們在外面調(diào)用 throw 方法后,在生成器函數(shù)中捕獲異常,會發(fā)生什么呢?我們來看下面的例子。

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

當(dāng)我們在生成器函數(shù)捕獲來自 throw 方法拋出的異常后,生成器依然是 valid 的。但是如果像剛才一樣只是在調(diào)用 throw 方法,那么生成器就結(jié)束了。

在生成器函數(shù)中拋出異常
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

之前我們看到的是調(diào)用 throw 方法來拋出異常。那么在生成器函數(shù)中,拋出一個異常而沒有在生成器函數(shù)中捕獲,結(jié)果也都是一樣的。同樣的,如果在生成器函數(shù)中捕獲了異常,那么就和之前的例子一樣了。

在理解了上面的例子之后,我們就要考慮一下,如果有嵌套的生成器,會發(fā)生什么了。

嵌套生成器

當(dāng)我們在一個生成器函數(shù)中,yield 了另外一個生成器函數(shù)之后,就會變成嵌套生成器。我們來看下面的例子。

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

對于嵌套的生成器來說,如果子生成器中拋出了異常,那么在沒有捕獲這個異常的情況下,會一級一級向上拋出,直到結(jié)束。

剛才我們嘗試了,在拋出異常之后,valid 的返回值變成了 false。那么在嵌套生成器中,是不是也是這樣呢?我們把異常捕獲,使程序能夠繼續(xù)執(zhí)行下去,來看下面這個例子。

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

所以,當(dāng)子生成器拋出異常后在迭代的過程中被正常地捕獲,那么,父生成器便不會受到影響,valid 的返回值依然是 true。

總結(jié)

關(guān)于生成器的異常處理,這里來進(jìn)行一下總結(jié)。

在生成器中拋出一個異常,或者使用 throw 方法拋出一個異常,那么,生成器的迭代便會結(jié)束,valid 變成 false;

在生成器中拋出一個異常,迭代過程中對異常進(jìn)行捕獲,生成器的迭代依然會結(jié)束,valid 依然會變成 false

在生成器中拋出一個異常,在生成器中將其捕獲處理,生成器的迭代不會結(jié)束,valid 會返回 true

在嵌套的生成器中,如果子生成器拋出了異常,只會對子生成器產(chǎn)生影響,不會對父生成器產(chǎn)生影響。

后記

yield 為我們提供了使用 PHP 實(shí)現(xiàn)半?yún)f(xié)程的工具。最近在研究使用 yield 實(shí)現(xiàn)半?yún)f(xié)程,而這個過程中,對異常的處理,是非常重要的。但是 yield 的運(yùn)行方式?jīng)Q定了異常處理比較難以理解。于是我花了幾天的時間,嘗試了各種可能,得出來的這些結(jié)論。當(dāng)然由于本人水平有限,如有錯誤,還望指點(diǎn)一二,不勝感激。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/25663.html

相關(guān)文章

  • 高質(zhì)量 Node.js 微服務(wù)編寫和部署

    摘要:編寫代碼的開發(fā)人員必須負(fù)責(zé)代碼的生產(chǎn)部署。構(gòu)建和部署鏈需要重大更改,以便為微服務(wù)環(huán)境提供正確的關(guān)注點(diǎn)分離。該對象會在之后的時被這時的回調(diào)函數(shù)會被調(diào)用,并輸出。微服務(wù)部署及集成部署微服務(wù)時有一個原則一個容器中只放一個服務(wù),可以使用編 前幾天在微信群做的一次分享,整理出來分享給大家,相關(guān)代碼請戳 https://github.com/Carrotzpc/docker_web_app sho...

    szysky 評論0 收藏0
  • 高質(zhì)量 Node.js 微服務(wù)編寫和部署

    摘要:編寫代碼的開發(fā)人員必須負(fù)責(zé)代碼的生產(chǎn)部署。構(gòu)建和部署鏈需要重大更改,以便為微服務(wù)環(huán)境提供正確的關(guān)注點(diǎn)分離。該對象會在之后的時被這時的回調(diào)函數(shù)會被調(diào)用,并輸出。微服務(wù)部署及集成部署微服務(wù)時有一個原則一個容器中只放一個服務(wù),可以使用編 前幾天在微信群做的一次分享,整理出來分享給大家,相關(guān)代碼請戳 https://github.com/Carrotzpc/docker_web_app sho...

    Michael_Ding 評論0 收藏0
  • 《Node.js設(shè)計(jì)模式》基于ES2015+回調(diào)控制流

    摘要:以下展示它是如何工作的函數(shù)使用構(gòu)造函數(shù)創(chuàng)建一個新的對象,并立即將其返回給調(diào)用者。在傳遞給構(gòu)造函數(shù)的函數(shù)中,我們確保傳遞給,這是一個特殊的回調(diào)函數(shù)。 本系列文章為《Node.js Design Patterns Second Edition》的原文翻譯和讀書筆記,在GitHub連載更新,同步翻譯版鏈接。 歡迎關(guān)注我的專欄,之后的博文將在專欄同步: Encounter的掘金專欄 知乎專欄...

    LiuRhoRamen 評論0 收藏0
  • es6 Generators詳解

    摘要:每個任務(wù)必須顯式地掛起自己,在任務(wù)切換發(fā)生時給予它完全的控制。在這些嘗試中,數(shù)據(jù)經(jīng)常在任務(wù)之間共享。但由于明確的暫停,幾乎沒有風(fēng)險。 翻譯自 github 概述 什么是generators? 我們可以把generators理解成一段可以暫停并重新開始執(zhí)行的函數(shù) function* genFunc() { // (A) console.log(First); yi...

    zhaot 評論0 收藏0
  • 異步編程解決方案 - generator

    摘要:異步編程解決方案事件發(fā)布訂閱模式訂閱,發(fā)布事件監(jiān)聽是一種高階函數(shù)的應(yīng)用,通過事件可以把內(nèi)部數(shù)據(jù)傳遞給外部的調(diào)用者,編程者可以不用關(guān)心組件內(nèi)部如何執(zhí)行,只需關(guān)注在需要的事件點(diǎn)上即可。 異步編程難點(diǎn) 異常處理 在處理異常時經(jīng)常用try/catch/final語句塊進(jìn)行異常捕獲,但是這種異常捕獲對異步編程并不是用 function async(callback) { process....

    AbnerMing 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<