- Добавлена документация SLM-архитектуры, базовых правил и прикладных разделов - Добавлены разделы: стили, SVG-спрайты, шаблоны генерации, PostCSS, REST, Realtime - Удалены устаревшие файлы (спрайты, скрипты, стили из app/)
83 lines
3.2 KiB
Markdown
83 lines
3.2 KiB
Markdown
---
|
||
title: Параллельные серверные запросы
|
||
description: Как запускать независимые REST-запросы на сервере без waterfall.
|
||
keywords: [rest, promise.all, параллельные запросы, server components]
|
||
---
|
||
|
||
# Параллельные серверные запросы
|
||
|
||
Если серверному компоненту нужно несколько независимых данных, запускайте запросы до ожидания результата. Последовательный `await` создаёт waterfall и замедляет рендер.
|
||
|
||
## Когда использовать
|
||
|
||
- Запросы независимы друг от друга.
|
||
- Все данные нужны текущему серверному компоненту перед возвратом UI.
|
||
- Нельзя или не нужно стримить часть UI отдельно.
|
||
|
||
## Хорошо
|
||
|
||
```tsx
|
||
import { petStoreApi } from 'infrastructure/pet-store-api'
|
||
import { PetsDashboardScreen } from 'screens/pets-dashboard'
|
||
|
||
export default async function PetsDashboardPage() {
|
||
const availablePetsPromise = petStoreApi.pet.findPetsByStatus({ status: 'available' })
|
||
const pendingPetsPromise = petStoreApi.pet.findPetsByStatus({ status: 'pending' })
|
||
const soldPetsPromise = petStoreApi.pet.findPetsByStatus({ status: 'sold' })
|
||
|
||
const [availablePets, pendingPets, soldPets] = await Promise.all([
|
||
availablePetsPromise,
|
||
pendingPetsPromise,
|
||
soldPetsPromise,
|
||
])
|
||
|
||
return (
|
||
<PetsDashboardScreen
|
||
availablePets={availablePets}
|
||
pendingPets={pendingPets}
|
||
soldPets={soldPets}
|
||
/>
|
||
)
|
||
}
|
||
```
|
||
|
||
## Плохо
|
||
|
||
```tsx
|
||
export default async function PetsDashboardPage() {
|
||
const availablePets = await petStoreApi.pet.findPetsByStatus({ status: 'available' })
|
||
const pendingPets = await petStoreApi.pet.findPetsByStatus({ status: 'pending' })
|
||
const soldPets = await petStoreApi.pet.findPetsByStatus({ status: 'sold' })
|
||
|
||
return (
|
||
<PetsDashboardScreen
|
||
availablePets={availablePets}
|
||
pendingPets={pendingPets}
|
||
soldPets={soldPets}
|
||
/>
|
||
)
|
||
}
|
||
```
|
||
|
||
Во втором примере каждый следующий запрос ждёт предыдущий, хотя они независимы.
|
||
|
||
## Зависимые запросы
|
||
|
||
Если второй запрос зависит от результата первого, последовательный `await` допустим:
|
||
|
||
```tsx
|
||
export default async function OrderPage({ params }: OrderPageProps) {
|
||
const { id } = await params
|
||
const order = await petStoreApi.store.getOrderById(Number(id))
|
||
const pet = await petStoreApi.pet.getPetById(order.petId)
|
||
|
||
return <OrderScreen order={order} pet={pet} />
|
||
}
|
||
```
|
||
|
||
Не превращайте зависимый сценарий в `Promise.all` искусственно.
|
||
|
||
## Когда выбрать другую стратегию
|
||
|
||
Если часть данных не обязательна для первого блока UI, можно запустить промис выше и передать его ниже: [Передача промиса ниже](./pass-promise-down.md).
|