Различное поведение, чтобы дать обещание между простым генератором и сагой Redux - PullRequest
0 голосов
/ 17 января 2019

Как я знаю, вы не можете получить обещание yield обещанием в генераторе. И следующий тест доказывает, что это правда. ret не определено:

function* foo() {
  const ret = yield Promise.resolve(50);
  console.log(`ret is ${ret}`);
}

const fooGen = foo();
fooGen.next();
fooGen.next()

Но я не могу понять, почему я могу получить значение разрешенного обещания в саге Redux. Смотрите следующий пример (jsfiddle: https://jsfiddle.net/vymgr7de/1/)

// Sagas
function* saga() {
  yield call(function*() {
    const ret = yield Promise.resolve(50);
    yield put({type: "*", payload: `ret is ${ret}`});
  });
}

// => ret is 50

Какой трюк играет Redux Saga?

1 Ответ

0 голосов
/ 17 января 2019

Чтобы расширить мой комментарий, приведу пример кода, который делает нечто подобное

function * test() {
    const result = yield new Promise(resolve => setTimeout(() => resolve('foo'), 1000))
    console.log('Result is: ', result)
}

function run(gen) {
    const iter = gen()
    const makeStep = (err, value) => {
        const step = !err ? iter.next(value) : iter.throw(err)
        if (step.done) return
        const p = step.value instanceof Promise ? step.value : Promise.resolve(step.value)
        p.then(val => makeStep(null, val), err => makeStep(err))
    }
    makeStep()
}

run(test)

Как видите, я перебираю генератор, и всякий раз, когда я нахожу обещание, я жду, пока оно не будет разрешено, и затем передаю разрешенное значение в iter.next(value). Если я найду что-то еще, я преобразую его в разрешенное обещание, чтобы Выражение yield мгновенно превращается во все, что было получено.

Конечно, Redux-Saga ищет не только обещания, но и всевозможные эффекты, каждый из которых имеет свою определенную функциональность.

...