Pull to refresh

Comments 22

Как избежать огромной портянки кода, подскажите кто-нибудь? Насколько я вижу, нужно на каждый запрос писать приличную такую кипу шаблонного кода, на большом проекте это будет выглядеть не слишком-то юзабельно, как мне кажется.

Это и правда неюзабельно. Но еще подождите людей со стокгольмским синдромом)

Вопрос к тем, кто использует саги вместо thunk: а что именно в saga-ах вам понравилось больше, чем практически точно такой же async-await код + redux-thunk? Из статьи не совсем ясно. Пассаж про декларативность вызывает лишь улыбку (не ерунда же). У этого подхода (который, как мне показалось, в основном заключается в написании yield вместо await) есть какие-то более конкретные преимущества?

А почему декларативность вызывает улыбку? Как мне показалось основной фишкой саг является именно попытка перевести разработку на декларативные рельсы с помощью эффектов-объектов (call, put & etc). А yield это всего лишь инструмент для этого.

Ну просто это скорее декорация декларативности, нежели какая-то настоящая декоративность. Чем-то напоминает карго-культ. Каждая стадия конечного автомата генератора императивна. Да и генератор всё равно будет раскручен полностью. Async функции работают точно по тому же принципу, но запускаются JS-движком напрямую, а не через redux-saga. Какой-то существенной разницы я не вижу. Но звёздочки короче, тут спору нет :)

Это все же не так. Саги действительно декларативны — в том смысле, что итерация по генератору не вызывает выполнение сайд эффектов. Вместо этого генератор возвращает описание сайд эффектов в виде объекта-обертки (из примера в статье — вместо прямого вызова fetch() и возврата результата промиса вызывается эффект call(), который, вопреки названию, НЕ вызывает обернутую функцию :) ). Это позволяет более просто тестировать сагу (например, как здесь)

О. Спасибо за пример. Так намного понятнее. Async-и так не потестишь, и правда :)

tl;dr: Используйте saga если у вас сложное приложение, используйте thunk если вас все
устраивает.


Лично я пользовался и тем, и другим. Разница между ними довольна большая.
redux-thunk удобный, простой как 5 копеек. Сайд эффекты описываются непосредственно в самих экшенах и вызываются как обычные.
redux-saga чуть более сложный и гибкий инструмент. Использует систему подписок — т.е. сага может быть вызвана на любой угодный вам экшен. Под гибкостью я имею ввиду более развитую систему эффектов — можно устраивать гонки эффектов, можно отменять действия и т.п.
Сравним на примере простой игры: надо нажать на кнопку и за 5 секунд сделать какое-то определенное действие, иначе проигрыш. В саге такое будет сделано за несколько строчек — гонка таймера и ожидание нового экшена. В redux-thunk сделать схожее уже на порядок сложнее.
Нельзя не отметить тестирование саг — очень простое и приятное занятие :)
Если у вас нет каких-то сложных действий используйте thunk, но если вы хотите больший контроль над потоком данных, удобное тестирование то saga ваш выбор.

Спасибо за разъяснение.


надо нажать на кнопку и за 5 секунд сделать какое-то определенное действие, иначе проигрыш. В саге такое будет сделано за несколько строчек — гонка таймера и ожидание нового экшена

Впечатляет. А можно, если не сложно, пример такой саги. Это одна сага или это две саги которые друг о друге что-то знают?

Ошибся веткой при ответе :)
Получается только одна сага. Вот пример:
export function* startGame() {
  const { winCondition, timeout } = yield race({
    winCondition: take('WIN'),
    timeout: call(delay, 5000)
  })
  if (winCondition) {
    console.log("Yeee, you've just won!")
  } else {
    console.log("Oh, nooo! Time out")
  }
}


Как звучит красиво, какие заумные слова: сага, функция-генератор… В итоге вы получаете огромный и сложно поддерживаемый код, добавьте к этому и flow-types. Чтобы сделать обычный запрос и получить обычный ответ, вам надо создавать 5 файлов и везде писать много кода. Вместе того, чтобы делать само приложение, вы будете только и разгребать весь этот мусор. Я не понимаю, кто это придумал: делать кучу телодвижений внутри самого приложения (dispatches, actions, actions-types, reducers, sagas) вместо того, чтобы сделать один простой запрос к серверу. Один простой запрос! Я когда-то читал все эти статьи с заумными заголовками, делал по всем этим стандартам. Думал, всё продумано и это хорошо работает. Но оказалось, что это пустой, бессмысленный и беспощадный хайп. Поэтому перехожу на graphql и apollo.
И в чем будет выгода? Вы сделаете все тоже самое для gql запроса.
Нет, там пишешь запрос и тут же обрабатываешь loading, error и data. И всё. Просто всё. Без всяких диспатч-шмитспатч, редюсер… Но, правда, там есть другая проблема — нет никакой инвалидации кэша на клиенте. Вообще никак это не предусмотрено. Просто убило меня это.
Я новичок в JS, может у меня глупый вопрос.
Какая связь между отказом от саг и переходом на GraphQL?
Apollo GraphQL решает проблемы сайд эффектов, которые в большинстве проектах решает redux-saga.
Сайд-эффект по отношению к стейту?
Друзья, коллеги, доброго времени суток!

Объясните мне пожалуйста, почему автор утверждает, что конструкции:
fetch(url).then(val => {
    console.log(val)
})

и
var val = yield fetch(url);
console.log(val);

идентичны?

Ведь в первом варианте перменная val будет содержать результат запроса, который был передан в resolve функцию. А во втором случае val будет содержать Promise, состояние которого нам ещё нужно обработать.

Может быть автор хотел сказать, что «с помощью саги» (а не генератора) это будут идентичные выражения. Но, насколько я понимаю, это тоже неверно: чтобы эти варианты были едентичны, необходимо во втором случае fetch обернуть в saga/effects метод, например call, чтобы middleware распаковал значение промиса и вернул его в value.

Что-то вроде этого:
var val = yield call(fetch, url);
console.log(val);

Так, как это описано в статье — работать не должно. Или я чего-то не догоняю?

Да, имелся в виду генератор, который запускается middleware'ой.


Но, насколько я понимаю, это тоже неверно

yield'ить можно и промисы, middleware его подождет и без оборачивания в call. Но таким образом теряется декларативность и по возможности лучше так не делать :)

Понял, спасибо! Пока только разбираюсь с сагами, не знал что она умеет корректно обработать промис и без «эффектов».
Если есть несколько запросов, takeEvery стартует несколько экземпляров саги-рабочего

Скорее «рабочей саги»
Sign up to leave a comment.

Articles