溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何使用spatie/async庫來寫異步的PHP代碼

發(fā)布時(shí)間:2020-11-10 10:03:34 來源:億速云 閱讀:117 作者:小新 欄目:編程語言

如何使用spatie/async庫來寫異步的PHP代碼?這個(gè)問題可能是我們?nèi)粘W(xué)習(xí)或工作經(jīng)常見到的。希望通過這個(gè)問題能讓你收獲頗深。下面是小編給大家?guī)淼膮⒖純?nèi)容,讓我們一起來看看吧!                                      

對于大多數(shù)用 PHP 編寫的程序,它的唯一目的是執(zhí)行由多個(gè)任務(wù)組成的簡單進(jìn)程,其中任務(wù)必須按順序執(zhí)行,如數(shù)據(jù)處理。我們總是不得不忍受同步編程的停止和等待。代碼執(zhí)行的同步風(fēng)格被稱為阻塞,這意味著任務(wù)將一個(gè)接一個(gè)地執(zhí)行。那么,如果我們想要運(yùn)行任務(wù)而不讓它們相互阻塞,這意味著我們需要一個(gè)非阻塞進(jìn)程,那該怎么辦呢?這種方法需要在 PHP 中應(yīng)用異步編程方法,這里的任務(wù)將在不相互依賴的情況下執(zhí)行。

在 PHP 中實(shí)現(xiàn)非阻塞執(zhí)行的一種常見方法是實(shí)現(xiàn)隊(duì)列處理。任務(wù)被持久保存到 MySQLRedis、Amazon SQS 等傳輸系統(tǒng)中,該傳輸系統(tǒng)由后臺 worker 檢索并相應(yīng)地執(zhí)行,從而不會(huì)阻塞創(chuàng)建任務(wù)的主進(jìn)程。Laravel 應(yīng)用程序提供了一種隊(duì)列機(jī)制,允許將任務(wù)(在本例中稱為作業(yè))推遲到稍后的時(shí)間進(jìn)行處理。

另一種方法是并行運(yùn)行所有定義的任務(wù)。我們從這種方法中知道的是,特定的任務(wù)完成后,它可以立即將控制權(quán)交還主進(jìn)程,并承諾執(zhí)行代碼并在稍后通知我們結(jié)果(例如回調(diào))。人們可能很少看到并行處理方法的用例;示例用例可能是執(zhí)行圖像處理并向某些外部服務(wù)發(fā)出 GET 請求。

讓我們通過一個(gè)非常簡單的用例來看看 PHP 中同步和異步(并行)流程之間的區(qū)別。

同步代碼

foreach (range(1, 5) as $i) {
    $output = $i * 2;
    echo $output . "\n";
}

異步代碼

use Spatie\Async\Pool;

$pool = Pool::create();

foreach (range(1, 5) as $i) {
    $pool[] = async(function () use ($i) {
       $output = $i * 2;
       return $output;
    })->then(function (int $output) {
       echo $output . "\n";
    });
}
await($pool);

當(dāng)我們執(zhí)行第一個(gè)代碼時(shí),我們將按以下順序獲得輸出值:

2
4
6
8
10

重試執(zhí)行,我們將獲得與上面相同的順序的輸出。因此,每個(gè)乘法運(yùn)算都要在下一個(gè)乘法運(yùn)算之前等待執(zhí)行。接下來,運(yùn)行第二個(gè)代碼塊,讓我們看看我們得到了什么。

6
10
2
8
4

第二次重試執(zhí)行:

2
6
4
10
8

一個(gè)過程產(chǎn)生兩個(gè)不同的結(jié)果。這正是我們使用異步方法所得到的結(jié)果。我們的小任務(wù)可以以一種互不阻塞的方式執(zhí)行。每個(gè)乘法任務(wù)都是獨(dú)立執(zhí)行的,有些執(zhí)行得比其他任務(wù)快,因此輸出結(jié)果混亂無序。另外,請注意我們的異步函數(shù)作為 then 方法附加,該方法負(fù)責(zé)取回控制權(quán),并且它接受回調(diào)函數(shù)作為其參數(shù),該回調(diào)函數(shù)現(xiàn)在可以對接收到的輸出執(zhí)行額外的操作。

Spatie 的工作人員開發(fā)了這個(gè)很好的spacee/async包,它有助于并行執(zhí)行任務(wù)。你可以通過 Composer 安裝該包:

composer require spatie/async

該包提供了一種巧妙的方式來與創(chuàng)建的任務(wù)進(jìn)行交互,這些任務(wù)將被并行執(zhí)行。任務(wù)的事件監(jiān)聽器描述如下:

  • 當(dāng)任務(wù)完成時(shí)再執(zhí)行一次操作,是因?yàn)榛卣{(diào)可以通過它的then方法來實(shí)現(xiàn)。
  • 當(dāng)一個(gè)特定的任務(wù)使用catch方法拋出異常時(shí),錯(cuò)誤處理更容易控制。
  • 當(dāng)一個(gè)任務(wù)沒有完成其操作時(shí),timeout方法允許人們處理這樣的場景。

事件監(jiān)聽器與如下所示的任務(wù)掛鉤:

$pool
    ->add(function () {
        // 要在并行進(jìn)程中執(zhí)行的任務(wù)
    })
    ->then(function ($output) {
        // 如果成功,進(jìn)程或者你傳遞到隊(duì)列的回調(diào)函數(shù)會(huì)返回`$output`。
    })
    ->catch(function ($exception) {
        // 當(dāng)進(jìn)程內(nèi)拋出異常時(shí),它會(huì)被捕獲并傳遞到這里。
    })
    ->timeout(function () {
        // 哦,不! 一個(gè)過程花了太長時(shí)間才完成。 讓我們做點(diǎn)什么吧
    })
;

感謝各位的閱讀!看完上述內(nèi)容,你們對如何使用spatie/async庫來寫異步的PHP代碼大概了解了嗎?希望文章內(nèi)容對大家有所幫助。如果想了解更多相關(guān)文章內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

php
AI