Отправка параметров и несколько одновременных запросов. React + Redux-saga. [Pt. 2]

В прошлой части  мы узнали о сагах, почему их можно использовать вместо альтернативного подхода внедрения запросов прямо в тело компонента и как создать простое действие с помощью саг.

Но это скучно.

Ведь мы все хотим совершать десятки запросов по несколько мегабайт каждый. Приступим.

function* fetchQuote(action) {
    try {
        const quote = yield call(requestYodified, action.text);
        const spellcheckedQuote = yield call(spellcheck, quote.data);

        yield put({type: success, quote: quote.data, spellcheckData: spellcheckedQuote.data});
    } catch (e) {
        yield put({type: fail, message: e.message});
    }
}

Как можно заметить, изменения по сравнению с прошлой версией огромны.

Поставив шутки в угол, кроме небольшого переименования переменных, добавлена всего одна строка. При этом мы вернулись к call и даже передали оба раза второй аргумент – переменную, которую мы хоть отдать функции совершающей запрос. Если мы захотим добавить больше данных – передаем больше переменных или оборачиваем все в объект – к чему душа больше лежит.

К сожалению апи от Йоды опять полетел именно в тот момент, когда я попытался проверить работу последовательных запросов.

Ненадежен, Йода, ты же как…

Поэтому почему бы не расширить немного обработку ошибок – к примеру, чтобы совсем не разочаровывать пользователя сообщением о ошибке, мы проверим как у него с орфографией!

...
catch (e) {
    try {
        const spellcheckedQuote = yield call(spellcheck, action.text);
        yield put({
            type: spellchecked, results: spellcheckedQuote.data
        });
    }
    finally {
        yield put({type: fail, message: e.message});
    }
}

Таким образом мы можем, к примеру, вывести результат выполнения части запросов, если это более выгодно по сравнению с полной остановкой из-за ошибки где-то на промежуточном этапе работы. А за время работы над “неудачным” сценарием, Йода поднялся и приготовился к работе – можно отдать ему какой-нибудь текст для перевода в человеческий – к примеру, заголовок нашего приложения “Welcome to React sagas!”, спустя несколько долгих секунд раздумий Йода наконец отвечает “To react sagas welcome! Herh herh herh.”. Вот и замечательно.

    {
    type: 'QuoteFetchRequest@Front',
    text: 'Welcome to React sagas!'
    }

    {
    type: 'QuoteFetchSucceeded@Saga',
    quote: 'To react sagas welcome! Herh herh herh.',
    spellcheckData: {
        original: 'To react sagas welcome! Herh herh herh.',
        suggestion: 'To react sagas welcome Hersh her her.',
        corrections: {
        Herh: [
        'Hersh', ...
        ],
        herh: [
        'her.', ...
        ] } }
    }

С последовательными запросами мы разобрались – добавить еще десяток-другой в цепочку, чтобы заставить пользователя ждать минутами, дело техники и сокровенной комбинации ctrl+c -> ctrl+v. Осталось научиться делать одновременно много, как некогда почивший салат.

function* fetchQuoteWhilSpellchecking(action) {
    try {
        const [quote, spellcheckedText] = yield all([
            call(requestYodified, action.text),
            call(spellcheck, action.text)
        ]);

        yield put({type: success, quote: quote.data, spellcheckData: spellcheckedText.data});
    } catch (e) {
        yield put({type: fail, message: e.message});
    }
}

Как вновь видно – изменений очень много.

Функция all – очередной вспомогательный элемент saga, позволяет создать несколько запросов и, дождавшись выполнения каждого, продолжить выполнение саги с полученными значениями. Запись вида const [a, b, c] = [...] – альтернатива деструктуризации для массивов, ожидаемо переводит массив вида [3, 2, 4] в три переменные – a = 3, ...

Наяривание до десятка запросов опять же происходит старым, добрым и немого уставшим ctrl+c -> ctrl+v. Но помни, пользователь очень любит ждать и обладает наилучшим железом, чем больше количество и чем толще запросы выше качество запросов – тем лучше.

Совмещение последовательного и параллельного выполнения опять же банально – получив результат параллельной обработки создаем новый запрос, и так далее, смешивая в нужных пропорциях.

В следующем выпуске – Саги: интересные части. Эффекты, отложенное исполнение, комбинирование и предсказуемое ожидание действий.

Код опять же доступен в репо, помимо полного кода, там появился “индикатор” загрузки.

nil commento load