Документация для разработчиков
Темная тема

Асинхронные запросы

За счёт организации очереди асинхронных запросов можно добиться кратного сокращения времени выполнения запросов. Каждый объект клиента создаёт собственную очередь.

Метод добавления асинхронного запроса в очередь возвращает промис Promise (промис) – это объект, представляющий результат успешного или неудачного завершения асинхронной операции. , не дожидаясь фактического выполнения запроса. Чтобы узнать результат запроса, нужно «подождать» и «развернуть» промис, либо передать ему callback-функции, которые выполнятся при успешном или неуспешном заполнении промиса.

Если стоит простая задача передать серию запросов и обработать их результаты, то можно попросить клиент самостоятельно обработать очередь и вернуть все ответы. Ответы будут отсортированы в порядке времени получения ответа (могут не соответствовать порядку запросов):

use Bitrix\Main\Web\HttpClient;
use Bitrix\Main\Web\Uri;
use Bitrix\Main\Web\Http\Request;
use Bitrix\Main\Web\Http\Method;
use Bitrix\Main\Web\Http\ClientException;
	
$http = new HttpClient();
	
$urls = [
	'http://www.flowersweb.info/images/t/top1.jpg',
	'http://1с-битрикс.рф',
	'https://www.1c-bitrix.ru/',
];
	
foreach ($urls as $url)
{
	$request = new Request(Method::GET, new Uri($url));

	$http->sendAsyncRequest($request);
}
	
try
{
	foreach ($http->wait() as $response)
	{
		var_dump($response->getStatusCode());
	}
}
catch (ClientException $e)
{
	var_dump($e->getMessage());
}

Если же нужен более точный контроль, в том числе за порядком ответов, то без промисов не обойтись:

use Bitrix\Main\Web\HttpClient;
use Bitrix\Main\Web\Uri;
use Bitrix\Main\Web\Http\Request;
use Bitrix\Main\Web\Http\Method;
use Bitrix\Main\Web\Http\ClientException;
	
$http = new HttpClient();
	
$urls = [
	'http://www.flowersweb.info/images/t/top1.jpg',
	'http://1с-битрикс.рф',
	'https://www.1c-bitrix.ru/',
];
	
$promises = [];
	
// добавить запросы в очередь
foreach ($urls as $url)
{
	$request = new Request(Method::GET, new Uri($url));

	$promises[] = $http->sendAsyncRequest($request);
}
	
// выполнить промисы
foreach ($promises as $promise)
{
	try
	{
		$response = $promise->wait();
	
		var_dump($promise->getRequest()->getUri()->getHost());
		var_dump($response->getStatusCode());
	}
	catch (ClientException $e)
	{
		var_dump($e->getMessage());
	}
}

Также в метод промиса then можно передать две callback-функции: на случай успешного заполнения промиса и на случай ошибки. Из callback-функций можно организовать цепочки, последовательно вызывая then.

Callback-функция успешного заполнения промиса принимает на вход объект ответа ResponseInterface и обязана вернуть объект ответа. Callback-функция ошибки принимает на вход исключение ClientException и должна вернуть или выкинуть исключение.

use Bitrix\Main\Web\HttpClient;
use Bitrix\Main\Web\Uri;
use Bitrix\Main\Web\Http\Request;
use Bitrix\Main\Web\Http\Method;
	
$http = new HttpClient();
	
$urls = [
	'http://www.flowersweb.info/images/t/top1.jpg',
	'http://1с-битрикс.рф',
	'https://www.1c-bitrix.ru/',
];
	
// добавить запросы в очередь
foreach ($urls as $url)
{
	$request = new Request(Method::GET, new Uri($url));
	
	$promise = $http->sendAsyncRequest($request);
	
	// callback
	$promise->then(function ($response) use ($promise) {
		var_dump($promise->getRequest()->getUri()->getHost());
		var_dump($response->getStatusCode());
	
		return $response;
	});
}
	
// нужно выполнить промисы
$http->wait();

Если явно не вызывать обработку очереди (строка $http->wait();), то это будет сделано в background jobs ядра. Callback-функции будут вызваны, но увидеть их результат на экране будет невозможно, т.к. фоновые задания выполняются уже после отдачи контента. Это можно использовать, если не нужно показывать результаты обработки запросов – контент отгрузится пользователю быстрее, а запросы выполнятся на фоне (в примере нужно заменить var_dump() на AddMessage2Log()).



© «Битрикс», 2001-2024, «1С-Битрикс», 2024