0

如何修改以下代码以异步获取文章数据和热门文章?

class ArticleController
{
    public function viewAction()
    {
        // how get
        $article = $this->getArticleData();
        $topArticles = $this->getTopArticles();
    }

    private function getArticleData() : array
    {
        // return article data from db
    }

    private function getTopArticles() : array
    {
        // return top articles from db
    }
}
4

2 回答 2

3

来自异步文档页面的警告与此处相关:

目前有对异步的基本支持。例如,您当前可以编写调用其他异步函数的基本异步函数。 但是,我们目前正在敲定其他基础(例如异步数据库、调度和内存处理 API),这将是在生产中充分发挥异步潜力所必需的。不过,我们认为引入异步的概念和技术(即使具有基本功能)会很有用,以便让开发人员习惯语法和一些技术细节。

因此,不幸的是,您实际使用异步函数所需的原始数据库查询尚不可用。上面链接的文档讨论了异步函数的一般工作原理,并包括一个合并获取的示例,您现在可以使用异步函数执行此操作。

DB API 终将到来,但目前还不可用,抱歉!

于 2014-11-16T20:24:41.827 回答
2

HHVM 3.6 及更新版本

async功能信息

启用异步函数的两个 HHVM PHP 语言关键字是asyncawait. async将函数声明为异步。await挂起函数的执行,async直到得到由 表示的异步操作的结果await。可以使用的函数的返回值await是一个实现Awaitable<T>.

您在文档(1)中有一个示例。在语言规范中也有关于异步函数的讨论(2)

实际上我花了一些时间来了解如何使用和调用异步函数,所以我想你会发现更多有用的信息。

我们有这两个功能:foo()bar()

async function foo(): Awaitable<void> {
  print "executed from foo";
}
async function bar(int $n): Awaitable<int> {
  print "executed from bar";
  return $n+1;
}

让我们尝试一些方法来调用这两个函数:

foo();                  // will print "executed from foo"
bar(15);                // will print "executed from bar"
$no1 = bar(15);         // will print "executed from bar"
print $no1;             // will output error, because $number is not currently an `int`; it is a `WaitHandle`
$no2 = bar(15)->join(); // will print "executed from bar"
print $no2;             // will print 16

AsyncMysqlClient提示

与 MySQL 数据库的连接是使用AsyncMysqlClient::connect异步函数建立的,该函数返回ExternalThreadEventWaitHandle一个AsyncMysqlConnection.

您可以执行queryqueryfAsyncMysqlConnection. 注意:您发送给 a 的数据queryf已被函数正确转义。

您对 an 执行的查询会AsyncMysqlConnection返回AsyncMysqlQueryResult(当查询执行正常时)或AsyncMysqlQueryErrorResult(如果查询出错;那么您可以使用mysql_error(),mysql_errno()failureType()此类的成员处理错误)。两者都AsyncMysqlQueryResult扩展AsyncMysqlQueryErrorResult抽象AsyncMysqlResult类。


以下是您的类的可能实现:

class ArticleController {
  private AsyncMysqlConnection $connection;
  public async function viewAction(int $articleId): Awaitable<void> {
    $this->connection = await AsyncMysqlClient::connect( /* connection data */ );
    $article = await $this->getArticleData($articleId);
  }
  public async function getArticleData(int $id): Awaitable<?Vector> {
    $articleDataQuery = await $this->connection->queryf("SELECT * FROM articles WHERE id %=d", $id);
    if($articleDataQuery instanceof AsyncMysqlQueryErrorResult) {
      throw new Exception("Error on getting data: ".$articleDataQuery->mysql_error());
    }

    // Considering that $id represents a unique id in your database, then
    // you are going to get only one row from your database query
    // so you return the first (and only) row in the query result
    if($articleDataQuery->numRows() == 1) {
      return $articleDataQuery->mapRowsTyped()[0];
    }
    return null;
  }
} 

PS我希望这个答案还为时不晚,希望对您有所帮助。如果您认为这有用,请接受它。

于 2015-08-20T08:01:37.540 回答