我正在学习amphp。我想使用amphp中的事件循环将同步调用转换为异步调用。我的示例代码使用file_get_contents
作为示例阻止调用。
使用同步通话,如下所示:
$uris = [
"https://google.com/",
"https://github.com/",
"https://stackoverflow.com/",
];
$results = [];
foreach ($uris as $uri) {
var_dump("fetching $uri..");
$results[$uri] = file_get_contents($uri);
var_dump("done fetching $uri.");
}
foreach ($results as $uri => $result) {
var_dump("uri : $uri");
var_dump("result : " . strlen($result));
}
输出:
string(30) "fetching https://google.com/.."
string(34) "done fetching https://google.com/."
string(30) "fetching https://github.com/.."
string(34) "done fetching https://github.com/."
string(37) "fetching https://stackoverflow.com/.."
string(41) "done fetching https://stackoverflow.com/."
string(25) "uri : https://google.com/"
string(14) "result : 48092"
string(25) "uri : https://github.com/"
string(14) "result : 65749"
string(32) "uri : https://stackoverflow.com/"
string(15) "result : 260394"
我知道有artax可以异步进行呼叫。但是,我想学习如何正确地将阻塞代码转换为异步并发代码(而非并行)。我已经成功地使用amp并行实现了它。
我相信,如果我在amp中异步成功实现了正确的输出,将会是这样:
string(30) "fetching https://google.com/.."
string(30) "fetching https://github.com/.."
string(37) "fetching https://stackoverflow.com/.."
string(34) "done fetching https://google.com/."
string(34) "done fetching https://github.com/."
string(41) "done fetching https://stackoverflow.com/."
string(25) "uri : https://google.com/"
string(14) "result : 48124"
string(25) "uri : https://github.com/"
string(14) "result : 65749"
string(32) "uri : https://stackoverflow.com/"
string(15) "result : 260107"
我尝试使用以下代码:
<?php
require __DIR__ . '/vendor/autoload.php';
use Amp\Loop;
use function Amp\call;
Loop::run(function () {
$uris = [
"https://google.com/",
"https://github.com/",
"https://stackoverflow.com/",
];
foreach ($uris as $uri) {
$promises[$uri] = call(function () use ($uri) {
var_dump("fetching $uri..");
$result = file_get_contents($uri);
var_dump("done fetching $uri.");
yield $result;
});
}
$responses = yield $promises;
foreach ($responses as $uri => $result) {
var_dump("uri : $uri");
var_dump("result : " . strlen($result));
}
});
不是给我我期望的结果,而是给我这个错误:
string(30) "fetching https://google.com/.."
string(34) "done fetching https://google.com/."
string(30) "fetching https://github.com/.."
string(34) "done fetching https://github.com/."
string(37) "fetching https://stackoverflow.com/.."
string(41) "done fetching https://stackoverflow.com/."
PHP Fatal error: Uncaught Amp\InvalidYieldError: Unexpected yield; Expected an instance of Amp\Promise or React\Promise\PromiseInterface or an array of such instances; string yielded at key 0 on line 20
结果似乎也同步运行,而不是异步运行。
我应该如何正确做?
答案 0 :(得分:1)
您需要使用所使用功能的非阻塞实现。 ssh -l user_pi -p 1234 localhost
正在阻止。例如,您可以在file_get_contents
中找到非阻塞实现。如果将amphp/file
替换为file_get_contents
,它应该可以正常工作。