如何让 ES6 生成器等待承诺,就像在 redux-saga 中一样?
Posted
技术标签:
【中文标题】如何让 ES6 生成器等待承诺,就像在 redux-saga 中一样?【英文标题】:How do I make ES6 generators wait for promises, like in redux-saga? 【发布时间】:2018-04-28 04:09:28 【问题描述】:我读过生成器不会等待承诺。为什么redux-saga
中的生成器不是这种情况,如何让我自己的生成器等待?
例如,这个传奇:
takeLatest('FETCH_USER_REQUESTED', function*()
const fetchPromise = yield put(fetchUser());
const user = yield fetchPromise;
console.log(user)
yield 1
console.log(1)
)
将输出:
Promise
Object // <= user data fetched asynchronously
1
代替:
Promise
undefined
1
【问题讨论】:
yield
关键字不是等待返回值吗?你能告诉我你在哪里读到的吗?
我在这里读到了:***.com/questions/44083873/…
我错了。这是一个很好的解释。 ***.com/questions/34930735/…
【参考方案1】:
为什么 redux-saga 中的生成器不是这种情况,如何让我自己的生成器等待?
这个非常流行的信念,但是生成器本身与 Promise 或异步函数无关。生成器只是通过将一些资源和责任委托给上层函数来制作可中断的函数。
在redux-saga
的情况下,有两部分:独立的saga runner 进程和调度程序(https://github.com/redux-saga/redux-saga/blob/master/src/internal/runSaga.js),由sagaMiddleware.run()
命令启动,以及effects
反应,它将动作委托给主saga 进程。
所以,ES6 中最简单的进程管理器,它模拟redux-saga
行为,将是这样的(非常简化):
const ProcessManager = (() =>
let context = new WeakMap();
function PM(rootSaga, lastValue)
if(!context.has(rootSaga))
context.set(rootSaga, rootSaga())
const iterator = context.get(rootSaga);
const done, value = iterator.next(lastValue);
if(done)
context.delete(rootSaga)
return;
if(Promise.resolve(value) === value)
value.then((asyncValue) => PM(rootSaga, asyncValue))
else
PM(rootSaga, value)
return PM;
)()
const rootSaga = function* ()
yield new Promise(resolve => setTimeout(resolve, 500));
console.log('This will be printed after 500 ms from start');
yield new Promise(resolve => setTimeout(resolve, 500));
console.log('This will be printed after 1000 ms from start');
ProcessManager(rootSaga);
【讨论】:
以上是关于如何让 ES6 生成器等待承诺,就像在 redux-saga 中一样?的主要内容,如果未能解决你的问题,请参考以下文章
javascript - redux thunk 不等待任何承诺
redux thunk - 承诺完成后如何在嵌套数组中调度数据