이 글은 PHP 코루틴의 thunkify 자동 실행기에 대한 자세한 소개(코드)를 제공합니다. 필요한 친구들이 참고할 수 있기를 바랍니다.
자동 스케줄링 기능을 구현하기 전에 먼저 고차 기능을 이해하겠습니다.
# 先求值再传参 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下函数都是可以传参的
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); }); # output array(2) { [0]=> string(3) "foo" [1]=> string(3) "bar" }
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); }); # output array(2) { [0]=> string(3) "foo" [1]=> string(3) "bar" }
이것을 보면 여전히 혼란스러울 수 있지만 thunkify 함수는 실제로 우리에게 도움이 됩니다. 단지 콜백 함수로 고차 함수를 래핑할 뿐입니다
하지만 여기서 무슨 소용이 있을까요? 일반적인 시나리오에서는 사용자가 많지 않습니다(파이썬 장식과 유사하게 일부 사전 및 사후 함수를 간단히 래핑하는 데 사용될 수 있습니다).
하지만, 단, 제너레이터 코루틴
에서는 Thunkify 함수
를 사용하여 제너레이터 코루틴
의 자동 프로세스 관리를 수행할 수 있습니다. 生成器协程
里,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(); // 手动回调, 模拟自动执行基础理解 $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); # output string(1) "1" string(1) "2" # 如果我们打开上面的两个sleep()注释 # output # 等待2秒 string(1) "1" # 等待5秒 string(1) "2" # 因为这里我们的thunk里执行的实际函数是同步的代码,所以整体是阻塞的后续代码执行的
只要执行 autoCaller
函数,生成器就会自动迭代完成。这样一来,异步操作不仅可以写得像同步操作,而且一行代码就可以执行。
Thunkify函数并不是 生成器协程
函数自动执行的唯一方案。
因为自动执行的关键是,必须有一种机制,自动控制 生成器协程
autoCaller
함수가 실행되는 한 생성기는 자동으로 반복하여 완료됩니다. 이러한 방식으로 비동기 작업은 동기 작업처럼 작성될 수 있을 뿐만 아니라 한 줄의 코드로 실행될 수도 있습니다. 🎜🎜Thunkify 기능은 제너레이터 코루틴
기능의 자동 실행을 위한 유일한 솔루션은 아닙니다. 🎜🎜자동 실행의 핵심은 제너레이터 코루틴
함수의 흐름을 자동으로 제어하고 프로그램의 실행 권한을 받고 반환하는 메커니즘이 있어야 하기 때문입니다. 🎜🎜콜백 함수가 이를 수행할 수 있으며 Promise 객체도 마찬가지입니다. 🎜위 내용은 PHP 코루틴(코드)의 thunkify 자동 실행기 상세 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!