3

我正在阅读有关 amphp 的内容,但我对并行有疑问

示例代码:

<?php

require __DIR__ . '/vendor/autoload.php';

$client = new Amp\Artax\DefaultClient;
$promises = [];

$urls = [
    "http://google.com.br",
    "http://facebook.com.br",
    "http://xat.com/",
    "http://kobra.ninja/",
    "http://wikipedia.com",
    "http://manualdomundo.com.br",
    "http://globo.com",
    "http://gmail.com"
];

foreach ($urls as $url) {
    $promises[$url] = Amp\call(function () use ($client, $url) {
        // "yield" inside a coroutine awaits the resolution of the promise
        // returned from Client::request(). The generator is then continued.
        $response = yield $client->request($url);

        // Same for the body here. Yielding an Amp\ByteStream\Message
        // buffers the entire message.
        $body = yield $response->getBody();
        echo $url;
        return $url;
    });
}

$responses = Amp\Promise\wait(Amp\Promise\all($promises));

这段代码是全部运行 curl,还是等待 1 执行另一个?

4

2 回答 2

1

正如您从Amp 代码库中看到的那样,它将在同一个事件循环中运行您的所有请求。

鉴于您的请求正在被产生(yield $client->request($url)),并且它们在同一个事件循环中被产生,它们被同时调度。

我建议您通读这篇文章,特别是“异步开发:Amp 框架的工作原理”部分。我认为这将使引擎在幕后的工作方式更加清晰。

希望这会有所帮助。干杯! :)

于 2020-01-17T23:53:09.687 回答
0

这是使用stream_select功能。它没有以您所想的传统方式并行运行。它通过注册一个回调来工作,一旦流是可读/可写的,然后在您等待的特定承诺完成时返回。同时解决的所有其他 Promise 都已完成并缓存在各自的 Promise 中,等待您使用yieldor解开值Promise::onResolveAmp 的事件循环是管理多个套接字并为您处理并发的东西。

如果你想要一个基本的例子来了解它是如何工作的,我在 GitHub 上放了一个示例项目,它是两个类,但基于 Curl 而不是stream_selecthttps ://github.com/kwhat/requestful

7 个方法是设置 Promise 接口所需的全部。这里的所有魔法都基于传递给构造函数的两个回调以及 then/cancel 回调的包装器。

sendRequestAsync方法是创建并发 Curl 请求的方式。魔术都发生在任何 promise 的 wait() 回调中,它调用一个匿名函数,该函数在循环中调用实习生的 tick 方法。该tick()方法是解决所有承诺的方法,无论您调用哪个等待。

于 2020-01-12T03:16:18.357 回答