如何在hack中修改以下代码以异步获取文章数据和热门文章?
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
}
}
来自异步文档页面的警告与此处相关:
目前对异步有基本支持。例如,您可以 当前编写调用其他异步函数的基本异步函数。 但是,我们目前正在完成其他基础(例如异步 数据库、调度和内存处理 API),这将是必需的 在生产中充分发挥异步的潜力。不过,我们觉得, 介绍异步的概念和技术会很有用 (即使具有基本功能)为了让开发人员习惯 语法和一些技术细节。
因此,不幸的是,实际使用异步函数所需的原始数据库查询尚不可用。上面链接的文档讨论了异步函数的一般工作原理,并包括一个合并获取的示例,您现在可以对异步函数执行此操作。
DB API 最终会推出,但尚未推出,抱歉!
HHVM 3.6 及更高
版本 async
功能信息
启用异步功能的两个 HHVM PHP 语言关键字是
async
和await
。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
。
您可以在AsyncMysqlConnection
上执行query
或queryf
。注意:您发送到queryf
的数据由函数正确转义。
对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;
}
}
附言我希望现在这个答案还为时不晚,希望对您有所帮助。如果您认为这有用,请接受它。