The way PHP executes code is synchronous and serial, that is, the operation codes defined in PHP will be completed step by step one after another. If we need to perform a large number of operations in a session, or call an external API, this method of synchronously executing code may take a long time, causing the user to wait too long. This is a bad user experience. In this article, we look at how to perform long-running operations asynchronously.
Execute PHP tasks asynchronously in WordPress using WP Cron
We know that WordPress provides us withWP Cron System, to help us implement timing operations. The way we implement asynchronous PHP is to add some operations to the one-time task schedule after the current point in time, thereby deferring some operations that do not require immediate results.
For example, when WordPress posts a comment, it sends a notification email to the administrator. By default, this operation is performed synchronously. The email must be sent successfully before the system will prompt the user that the comment is successful. On some hosts, sending emails will be slower, which results in a longer user waiting time.
In fact, the administrator does not need to receive the notification email immediately. Even if it is received, the administrator may not have time to process it immediately. Therefore, we can first prompt the user that the comment is successful, and then wait until the set email sending task schedule time is up before sending the notification email.
The following function implements a simple function of sending emails asynchronously:
if ( ! defined( 'DOING_CRON' ) || ( defined( 'DOING_CRON' ) && ! DOING_CRON ) ) {
function async_send_wp_mail() {
// 获取 wp_mail 函数的参数
$args = func_get_args();
// 添加一个随机值以避免重复发送,参考: http://codex.wordpress.org/Function_Reference/wp_schedule_single_event
$args[] = mt_rand();
// 5 分钟之后发送邮件
wp_schedule_single_event( time() + 5, 'cron_send_mail', $args );
}
}
When sending emails, we can use the following code to send emails asynchronously.
add_action( 'cron_send_mail', function () {
$args = func_get_args();
// 移除上面添加的随机数
array_pop( $args );
call_user_func_array( 'wp_mail', $args );
}, 10, 10 );
Implement asynchronous PHP operations in WordPress using the WP Asynchronous Tasks library
The method of using WP Cron to send emails asynchronously is quite simple, but there are some efficiency issues. When there are a lot of emails, the delay may be relatively large. TechCrunch open sourceWP Asynchronous TasksThe library solves this problem. The implementation method is to add a random number as a task mark when the task is executed. Use this random number to verify whether the task is executed successfully. If the execution is successful, the postponed task will be executed.
For example, on the article page, we need to obtain several articles that have the same category or tag as the current article and display them as related articles. This is a relatively time-consuming MySQL query, and we generally need to use caching to optimize it. When the data is in the cache, the data in the cache is directly displayed. If the data is not in the cache, or the cache has expired, the data is obtained, added to the cache, and then displayed.
Because this is a time-consuming operation when browsing larger sites. If the cache is updated first and then displayed, the user may have to wait longer. In this operation, we can use an asynchronous method to optimize this operation. When displaying the page, directly display the data in the cache, and at the same time determine when the cache expires. If it is about to expire, add an asynchronous task to update the cache. In this way, cached data will always be displayed on the page.
According to TechCrunch, using WP Asynchronous Tasks at the right time canImprove WordPress page loading speedto the original 5-8 times. If your site encounters this problem, you can consider using this library for optimization.
Another similar library is developed by the developers of WP Migrate DB ProWP Background ProcessingLibrary, which adds simple task queue support based on WP Asynchronous Tasks. If a large number of time-consuming and repetitive operations need to be performed, what we need may be a complete database-basedWordPress task queue。
