如何让ES6生成器等待promx,比如redux-saga?

时间:2017-11-15 03:26:39

标签: javascript es6-promise redux-saga

我读过发电机不等待承诺。为什么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

1 个答案:

答案 0 :(得分:1)

  

对于redux-saga中的生成器,情况怎么样呢?如何让自己的生成器等待?

这种非常普遍的看法,但是生成器本身与Promises或异步函数无关。发电机只是通过将一些资源和责任委托给上层功能来实现可中断功能。

如果是redux-saga,则有两个部分:独立的saga runner进程和调度程序(https://github.com/redux-saga/redux-saga/blob/master/src/internal/runSaga.js),由sagaMiddleware.run()命令启动,以及effects个反应,它将行动委托给主要的传奇过程。

因此,模拟redux-saga行为的ES6中最简单的流程管理器就是这样(非常简化):

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);