国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > PHP > 正文

PHP協程的thunkify自動執行器的詳細介紹(代碼)

2020-03-22 19:44:47
字體:
來源:轉載
供稿:網友
本篇文章給大家帶來的內容是關于PHP協程的thunkify自動執行器的詳細介紹(代碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。

高階函數

在我們實現自動調度(器)函數前,我們先來理解下高階函數

thunk函數
# 先求值再傳參function func(m){ return m * 2; f(x + 5);// 等同于# 先傳參再求值var thunk = function () { return x + 5;function func(thunk){ return thunk() * 2;# 這段我們在python或一些語言里,概念叫高階函數# 因為php是解釋性動態語言,所以函數可以當參數傳入# 這里python,js,php下函數都是可以傳參的
PHP版本的thunkify函數

thunkify實現原理:

1、包裝一次原始函數名,然后返回一個第一次匿名函數(并攜帶包裝函數): return function () use ($func){$args = func_get_args();}

2、然后再獲取該匿名函數的參數,并在上一次第一次匿名函數體內返回一次帶回調參數的第二次匿名函數(并攜帶上一次環境上下文): return function ($callback) use ($args, $func){}

3、調用包裝函數,參數為:第一次匿名函數調用的參數+一個回調函數

function thunkify($func){ return function () use ($func) { $args = func_get_args(); return function ($callback) use ($args, $func) { array_push($args, $callback); return $func(...$args);$printStr = function($p1, $p2, $callback) { $callback($p1, $p2);$printStrThunkify = thunkify($printStr);$printStrThunkify(...[ foo , bar ])(function (...$p) { var_dump($p);# outputarray(2) { [0]=  string(3) foo  [1]=  string(3) bar }
只能執行一次回調的thunkify函數
function thunkify($func){ return function () use ($func) { $args = func_get_args(); return function ($callback) use ($args, $func) { // 原本的獲取參數,回調會多次執行 // array_push($args, $callback);  // 增加回調只能執行一次 $callbackCalled = false; array_push($args, function (...$params) use ($callback, $callbackCalled) { if ($callbackCalled) return ; $callbackCalled = true; $callback(...$params); return $func(...$args);$printStr = function($p1, $p2, $callback) { $callback($p1, $p2); $callback($p1, $p2); //我們增加一次回調$printStrThunkify = thunkify($printStr);$printStrThunkify(...[ foo , bar ])(function (...$p) { var_dump($p);# outputarray(2) { [0]=  string(3) foo  [1]=  string(3) bar }

看到這里,你可能還在疑惑,thunkify函數其實只是幫我們包裝了一次有回調函數的高階函數而已
不過這里到底有什么用處呢,在普通場景下確實用戶不大(可能用處單純就在做一些前后置函數包裝也是用處的,類似python的裝飾)
但是,但是,但是在生成器協程里,Thunkify函數可以用于生成器協程的自動流程管理。

生成器協程的自動執行基礎理解

每一次yield出來的結果都是一個thunk函數的回調

function thunkify($func){ return function () use ($func) { $args = func_get_args(); return function ($callback) use ($args, $func) { $callbackCalled = false; array_push($args, function (...$params) use ($callback, $callbackCalled) { if ($callbackCalled) return ; $callbackCalled = true; $callback(...$params); return $func(...$args);$printStr1 = function($p1, $callback) { $callback($p1);$printStr2 = function($p1, $callback) { $callback($p1);$printStrThunkify1 = thunkify($printStr1);$printStrThunkify2 = thunkify($printStr2);function gen() global $printStrThunkify1, $printStrThunkify2; $r1 = yield $printStrThunkify1( 1  var_dump($r1); $r2 = yield $printStrThunkify2( 2  var_dump($r2);$gen = gen();// 手動回調, 模擬自動執行基礎理解$html' target='_blank'>value = $gen- current();$value(function ($p1) use($gen) { $value = $gen- send($p1); $value(function ($p1) use($gen) { $value = $gen- send($p1); var_dump($value);});
自動執行器

我們這里只是實現上面的手動回調執行
增加了一個自動執行器,把生成器協程傳入后講自動執行生成器協程

function thunkify($func){ return function () use ($func) { $args = func_get_args(); return function ($callback) use ($args, $func) { $callbackCalled = false; array_push($args, function (...$params) use ($callback, $callbackCalled) { if ($callbackCalled) return ; $callbackCalled = true; $callback(...$params); return $func(...$args);$printStr1 = function($p1, $callback) { sleep(2); $callback($p1);$printStr2 = function($p1, $callback) { sleep(5); $callback($p1);$printStrThunkify1 = thunkify($printStr1);$printStrThunkify2 = thunkify($printStr2);function gen() global $printStrThunkify1, $printStrThunkify2; $r1 = yield $printStrThunkify1( 1  var_dump($r1); $r2 = yield $printStrThunkify2( 2  var_dump($r2);function autoCaller(/Generator $gen) // 注意這里的$next use 引入作用域必須帶上 , 否則無法識別 $next = function ($p1) use ($gen, $next) { if (is_null($p1)) { //此處獲取第一次yeild的回調 $result = $gen- current(); } else { // send后返回的是下一次的yield值 $result = $gen- send($p1); // 是否生成器迭代完成 // 迭代器生成完成,不再迭代執行(自動執行器返回停止) if (!$gen- valid()) { return ; $result($next); $next(null);$gen1 = gen();//$gen2 = gen();autoCaller($gen1);//autoCaller($gen2);# outputstring(1) 1 string(1) 2 # 如果我們打開上面的兩個sleep()注釋# output# 等待2秒string(1) 1 # 等待5秒string(1) 2 # 因為這里我們的thunk里執行的實際函數是同步的代碼,所以整體是阻塞的后續代碼執行的
總結

只要執行 autoCaller 函數,生成器就會自動迭代完成。這樣一來,異步操作不僅可以寫得像同步操作,而且一行代碼就可以執行。

Thunkify函數并不是 生成器協程 函數自動執行的唯一方案。

因為自動執行的關鍵是,必須有一種機制,自動控制 生成器協程 函數的流程,接收和交還程序的執行權。

回調函數可以做到這一點,Promise 對象也可以做到這一點。

以上就是PHP協程的thunkify自動執行器的詳細介紹(代碼)的詳細內容,PHP教程

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 普兰县| 英吉沙县| 犍为县| 卓资县| 武乡县| 屏山县| 财经| 德昌县| 汉川市| 玉龙| 额尔古纳市| 辉县市| 天津市| 桑植县| 革吉县| 霍城县| 米泉市| 黎城县| 南陵县| 连南| 古交市| 东海县| 库尔勒市| 固原市| 思南县| 都匀市| 皋兰县| 阳高县| 扎兰屯市| 林芝县| 棋牌| 芒康县| 克什克腾旗| 陆川县| 白沙| 高邮市| 涟水县| 顺昌县| 邵武市| 黑河市| 景德镇市|