首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在安普中正确地把闭包变成承诺?

如何在安普中正确地把闭包变成承诺?
EN

Stack Overflow用户
提问于 2018-10-05 12:17:48
回答 1查看 488关注 0票数 0

我在学安非他语。我想转换同步调用异步调用使用事件循环在安普。我的示例代码使用file_get_contents作为示例阻塞调用。

使用sync调用,它看起来如下所示:

代码语言:javascript
复制
$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));
}

和输出:

代码语言:javascript
复制
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中成功地在异步中实现它,正确的输出将是这样的:

代码语言:javascript
复制
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"

我试过使用下面的代码:

代码语言:javascript
复制
<?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));
    }
});

它给出的不是我预期的结果,而是这个错误:

代码语言:javascript
复制
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 

结果似乎也是同步运行,而不是异步运行。

我应该如何正确地做这件事?

EN

回答 1

Stack Overflow用户

发布于 2019-01-04 18:49:51

你需要使用一个非阻塞实现你所使用的函数。file_get_contents被阻塞。例如,您可以在amphp/file中找到非阻塞实现。如果您将file_get_contents替换为Amp\File\get,它应该会按预期工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52658288

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档