在普通生成器和 Redux saga 之间产生承诺的不同行为
Different behavior to yield a promise between a plain generator and Redux saga
据我所知,您无法通过 yield
生成器中的承诺获得承诺。而下面的测试证明这是真的。 ret
未定义:
function* foo() {
const ret = yield Promise.resolve(50);
console.log(`ret is ${ret}`);
}
const fooGen = foo();
fooGen.next();
fooGen.next()
但是我不明白为什么我可以在 Redux saga 中得到 resolved promise 值。请参阅以下示例 (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 玩什么花样?
这里有一个代码示例来扩展我的评论
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)
如您所见,我正在遍历生成器,每当我找到一个 promise 时,我都会等到它被解决,然后将已解决的值传递给 iter.next(value)
,如果我发现任何其他东西,我会将其转换为resolved Promise 因此 yield 表达式立即解析为它产生的任何内容。
当然,redux-saga 不仅在寻找 promises,还在寻找各种效果,每个效果都有自己定义的功能。
据我所知,您无法通过 yield
生成器中的承诺获得承诺。而下面的测试证明这是真的。 ret
未定义:
function* foo() {
const ret = yield Promise.resolve(50);
console.log(`ret is ${ret}`);
}
const fooGen = foo();
fooGen.next();
fooGen.next()
但是我不明白为什么我可以在 Redux saga 中得到 resolved promise 值。请参阅以下示例 (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 玩什么花样?
这里有一个代码示例来扩展我的评论
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)
如您所见,我正在遍历生成器,每当我找到一个 promise 时,我都会等到它被解决,然后将已解决的值传递给 iter.next(value)
,如果我发现任何其他东西,我会将其转换为resolved Promise 因此 yield 表达式立即解析为它产生的任何内容。
当然,redux-saga 不仅在寻找 promises,还在寻找各种效果,每个效果都有自己定义的功能。