首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我如何从ReactPHP\诺言中“提取”数据?

我如何从ReactPHP\诺言中“提取”数据?
EN

Stack Overflow用户
提问于 2019-06-13 06:19:57
回答 1查看 1.3K关注 0票数 2

免责声明:这是我第一次使用ReactPHP和"php承诺“,所以这个解决方案可能会直面我。

我目前正在做一个小项目,在那里我需要创建一个Slack。我决定使用博特曼包并使用它的Slack驱动程序。该驱动程序利用ReactPHP的承诺与RTM进行通信。

我的问题:

当我对命令进行bot应答时,我希望从RTM获得get检索响应,这样我就可以缓存发布消息的ID。

问题是,响应是在其中一个ReactPHP\Promise\Promise中返回的,但我不知道如何检索数据。

我在做什么:

因此,当一个命令被触发时,机器人会发送一个应答脚本:

代码语言:javascript
复制
$response = $bot->reply($response)->then(function (Payload $item) {
    return $this->reply = $item;
});

但是$response由一个(空的?) ReactPHP\Promise\Promise组成。

代码语言:javascript
复制
React\Promise\Promise^ {#887
  -canceller: null
  -result: null
  -handlers: []
  -progressHandlers: & []
  -requiredCancelRequests: 0
  -cancelRequests: 0
}

我也尝试过使用done()而不是then(),这就是(就我所能理解的) 官方的ReactPHP文档建议您应该使用它从承诺中检索数据。

代码语言:javascript
复制
$response = $bot->reply($response)->done(function (Payload $item) {
    return $this->reply = $item;
});

但是$responsenull的形式返回。

有趣的是,在调试过程中,我试图在then()中执行一个then(),但是忘了删除一个不存在的方法。但是var_dump实际上返回了数据

代码语言:javascript
复制
$response = $bot->reply($response)->then(function (Payload $item) {
    var_dump($item);
    return $this->reply = $item;
})->resolve();

因此,据我所知,似乎我需要再次“履行”承诺,即使它在被归还之前已经解决了。

在Bot的回复方法中,这就是正在发生的事情以及ReactPHP承诺是如何生成的:

代码语言:javascript
复制
public function apiCall($method, array $args = [], $multipart = false, $callDeferred = true)
{
    // create the request url
    $requestUrl = self::BASE_URL . $method;

    // set the api token
    $args['token'] = $this->token;

    // send a post request with all arguments
    $requestType = $multipart ? 'multipart' : 'form_params';
    $requestData = $multipart ? $this->convertToMultipartArray($args) : $args;

    $promise = $this->httpClient->postAsync($requestUrl, [
        $requestType => $requestData,
    ]);

    // Add requests to the event loop to be handled at a later date.
    if ($callDeferred) {
        $this->loop->futureTick(function () use ($promise) {
            $promise->wait();
        });
    } else {
        $promise->wait();
    }

    // When the response has arrived, parse it and resolve. Note that our
    // promises aren't pretty; Guzzle promises are not compatible with React
    // promises, so the only Guzzle promises ever used die in here and it is
    // React from here on out.
    $deferred = new Deferred();
    $promise->then(function (ResponseInterface $response) use ($deferred) {
        // get the response as a json object
        $payload = Payload::fromJson((string) $response->getBody());

        // check if there was an error
        if (isset($payload['ok']) && $payload['ok'] === true) {
            $deferred->resolve($payload);
        } else {
            // make a nice-looking error message and throw an exception
            $niceMessage = ucfirst(str_replace('_', ' ', $payload['error']));
            $deferred->reject(new ApiException($niceMessage));
        }
    });

    return $deferred->promise();
}

您可以看到它的全部来源,这里

请给我指点方向。我觉得我什么都试过了,但很明显我错过了什么或者做错了什么。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-13 14:58:45

这里是ReactPHP的核心团队成员。这里有几个选择和事情在进行。

首先,then永远不会从承诺中返回值,它将返回一个新的承诺,这样您就可以创建一个承诺链。因此,您将在每个异步操作中执行一个新的异步操作,然后接受上一个异步操作的结果。

第二,done从不返回结果值,它的工作方式与then非常相似,但是它会抛出链中先前承诺的任何不明确的异常。

thendone的特点是它们是您的解析方法。承诺a仅仅代表尚未完成的操作的结果。一旦操作就绪,它将调用您提交给then/donethen/done,并解决该承诺。因此,最终,您的所有操作都是以某种方式或在最广泛的意义上发生在callable中的。(它也可以是类上的__invoke方法,这取决于您如何设置它。还有为什么我对PHP 7.4中的短闭包如此兴奋。)

你在这里有两个选择:

  • callable中运行所有的操作
  • 使用RecoilPHP

前者意味着更多的心智映射,并学习异步如何工作,以及如何将您的思维围绕在这方面。后者使它更简单,但需要您在一个协同线中运行每条路径(callable带有一些很酷的魔力)。

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

https://stackoverflow.com/questions/56574410

复制
相关文章

相似问题

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