React Meetup Düsseldorf
    
    
    […] a Saga is like a separate thread in your application that's solely responsible for side effects.
function* generator() { /* ... */ }
const iterator = generator() // => Object
iterator.next() => { value: T | undefined, done: bool }
for (const item of iterator) { // calls iterator.next()
  console.log(item)
}
function* generator() {
  const num = 2
  // Pass value to callee and pause execution
  yield 1
  
  
  
  
  
  
}
const iterator = generator()
function* generator() {
  const num = 2
  // Pass value to callee and pause execution
  yield 1
  
  
  
  
  
  
}
const iterator = generator()
// Generator progress controlled from outside
iterator.next().value   == 1
function* generator() {
  const num = 2
  // Pass value to callee and pause execution
  yield 1
  // Callee can pass values into generator
  let a = yield 2
  
  
  
}
const iterator = generator()
// Generator progress controlled from outside
iterator.next().value   == 1
iterator.next().value   == 2
function* generator() {
  const num = 2
  // Pass value to callee and pause execution
  yield 1
  // Callee can pass values into generator
  let a = yield 2
  // `num` maintains value across yield points
  yield a + num
}
const iterator = generator()
// Generator progress controlled from outside
iterator.next().value   == 1
iterator.next().value   == 2
iterator.next(10).value == 12
function* generator() {
  const num = 2
  // Pass value to callee and pause execution
  yield 1
  // Callee can pass values into generator
  let a = yield 2
  // `num` maintains value across yield points
  yield a + num
}
const iterator = generator()
// Generator progress controlled from outside
iterator.next().value   == 1
iterator.next().value   == 2
iterator.next(10).value == 12
iterator.next().done    == true
function* saga() {
  yield put({
    type: "SET_JOKE",
    payload: "What do you call a fake noodle? An impasta!",
  })
}
saga().next() == {
  PUT: {
    action: {
      type: "SET_JOKE",
      payload: "What do you call a fake noodle? An impasta!",
    }
  }
}
function* fetchJoke() {
  const { joke } = yield call(
    fetchJson,
    "https://icanhazdadjoke.com/",
  )
  yield put({ type: 'SET_JOKE', payload: joke })
}
function* jokeThread() {
  while (true) {
    const action = yield take('GET_JOKE')
    yield fork(fetchJoke)
  }
}
App Lifecycle
Login → Interaction → Logout → Login …
function* app() {
  while (true) {
    yield waitForlogin()
    const pid = yield fork(runDataFetching)
    yield waitForLogout()
    yield cancel(pid)
  }
}
it("should fetch a joke and store it in the state", () => {
  const jokeMock = {
    joke: "Chuck Norris knows the last digit of pi."
  }
  const it = fetchJoke()
})
it("should fetch a joke and store it in the state", () => {
  const jokeMock = {
    joke: "Chuck Norris knows the last digit of pi."
  }
  const it = fetchJoke()
  it.next() // returns { CALL: { ... } } effect object
  
  
  
  
  
  
  
})
it("should fetch a joke and store it in the state", () => {
  const jokeMock = {
    joke: "Chuck Norris knows the last digit of pi."
  }
  const it = fetchJoke()
  it.next() // returns { CALL: { ... } } effect object
  expect(it.next(jokeMock).value).toEqual(put({ 
    type: "SET_JOKE", 
    payload: jokeMock.joke,
  }))
  
  
})
it("should fetch a joke and store it in the state", () => {
  const jokeMock = {
    joke: "Chuck Norris knows the last digit of pi."
  }
  const it = fetchJoke()
  it.next() // returns { CALL: { ... } } effect object
  expect(it.next(jokeMock).value).toEqual(put({ 
    type: "SET_JOKE", 
    payload: jokeMock.joke,
  }))
  expect(it.next())
    .toEqual({ done: true, value: undefined })
})
function* handleInput({ payload }) {
  yield delay(500)
  const res = yield call(
    fetch,
    "https://myAPI",
    { body: payload },
  )
}
function* watchInput() {
  yield takeLatest('INPUT_CHANGED', handleInput)
}
function* request() {
  while (true) {
    const res = yield call(fetch, "https://myAPI")
    
    if (res) {
      put(...)
      return
    }
    
    yield delay(5000)
  }
}
const io = {
  dispatch(action) => /* saga dispatches an action */,
  getState() => /* saga requests app state */,
  subscribe(callback) =>  /* on action: callback(action) */,
}
runSaga(io, saga)