PHP Fibers 返回 null 值

huangapple go评论61阅读模式
英文:

PHP Fibers return null values

问题

运行以下代码时,返回空值。我已经使用协程运行了该代码,并且使用的PHP版本是8.2。

期望输出:

Array
(
    [0] => "A" 
    [1] => "B"
    [2] => "C"
)

但在运行上述代码时,返回以下输出:

Array
(
    [0] => 
    [1] => 
    [2] => 
)
英文:

While running below code, it return empty values. I have used fibers to run the code and used PHP version is 8.2

<?php
  
$data=["A","B","C"];
$fibers = [];
foreach ($data as $val) {
    $fiber = new Fiber(function () use ($val): void {
        Fiber::suspend($val);
    });

    $fiber->start();
    $fibers[] = $fiber;
}

$results = [];
foreach ($fibers as $fiber) {

    $results[] = $fiber->resume();
}

print_r($results);
?>

Expected Output

Array
(
    [0] =>"A" 
    [1] =>"B"
    [2] =>"C"
)

While running above code return this output

Array
(
    [0] => 
    [1] => 
    [2] => 
)

答案1

得分: 1

$fiber->start();调用会消耗掉你的$val。根据文档,start()的返回值是第一个Fiber::suspend()调用传递的变量,如果函数返回了null,则返回null。resume()也是一样的,所以你对start()的调用已经返回了$val,然后就没有留下东西给resume()了。

你想要的结果可以通过以下代码实现:

<?php
      
$data=["A","B","C"];
$fibers = [];
foreach ($data as $val) {
    $fiber = new Fiber(function () use ($val): void {
        Fiber::suspend();
        Fiber::suspend($val);
    });

    $fiber->start();
    $fibers[] = $fiber;
}

$results = [];
foreach ($fibers as $fiber) {
    $results[] = $fiber->resume();
}

print_r($results);
?>

以下是一种在仍然使用Fiber的情况下进行重写的建议:

<?php
      
$data=["A","B","C"];
$fibers = [];

$callback = function ($val): string {
    Fiber::suspend();
    return $val;
};

foreach ($data as $val) {
    $fiber = new Fiber($callback);
    $fiber->start($val);
    $fibers[] = $fiber;
}

$results = [];
foreach ($fibers as $fiber) {
    $fiber->resume();
    $results[] = $fiber->getReturn();
}

print_r($results);
?>
英文:

The call to $fiber-&gt;start(); consumes your $val.
As per documentation the return value of start() is the variable given to the first Fiber::suspend() call or null if the function returned. resume() does the same, so your call to start() already returned $val and then there is nothing left for resume().

The result you want would be achieved with this code:

&lt;?php
  
$data=[&quot;A&quot;,&quot;B&quot;,&quot;C&quot;];
$fibers = [];
foreach ($data as $val) {
    $fiber = new Fiber(function () use ($val): void {
        Fiber::suspend();
        Fiber::suspend($val);
    });

    $fiber-&gt;start();
    $fibers[] = $fiber;
}

$results = [];
foreach ($fibers as $fiber) {
    $results[] = $fiber-&gt;resume();
}

print_r($results);
?&gt;

And here a suggestion for a rewrite while still using Fiber:

&lt;?php
  
$data=[&quot;A&quot;,&quot;B&quot;,&quot;C&quot;];
$fibers = [];

$callback = function ($val): string {
	Fiber::suspend();
	return $val;
};

foreach ($data as $val) {
    $fiber = new Fiber($callback);
    $fiber-&gt;start($val);
    $fibers[] = $fiber;
}

$results = [];
foreach ($fibers as $fiber) {
	$fiber-&gt;resume();
    $results[] = $fiber-&gt;getReturn();
}

print_r($results);
?&gt;

huangapple
  • 本文由 发表于 2023年3月9日 19:32:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/75684024.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定