Написание адаптера для Fetch API
Кажется, что нет такого проекта, в котором не нужно делать запросы к серверу. И всегда хорошей идеей написать отдельную абстракцию для описания подобной коммуникации. Это добавляет коду не только читаемости и переиспользуемости, но и дает возможность быстро и эффективно написать тест для подобной функциональности. class NetworkService { constructor(private readonly fetch: typeof fetch) {} getUser: (): Promise<IUser> => this.fetch('/api/user').then(d => d.json()) } function getUsername(api: Pick<NetworkService, 'getUser'>) { return api.getUser().then(user => user.name); } test('getUsername', async () => { const name = await getUsername({ getUser: () => Promise.resolve({ name: 'test' } as IUser) }); expect(name).toBe('test'); }); И для среднестатистического проекта такого подхода будет достаточно. Но иногда возникают требования, что нужно переопределить сам fetch. Например, у нас в проекте, мы разрабатываем extension для браузера и хотим делать запросы через serviceWorker. И возникает требования переимплементировать Fetch API. Как мы знаем fetch возвращает примитив Response, для создания которого нужно передать первым аргументом ReadableStream, а вторым характеристики ответа. Таким образом мы можем использовать следующую конструкцию. ...