本文介绍了如何让ES6生成器等待promx,比如redux-saga?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读过发电机不等待承诺。为什么 redux-saga 中的生成器不是这种情况,我如何让我自己的生成器等待?

I've read that generators don't wait for promises. How come this is not the case with generators in redux-saga, and how do I make my own generators wait?

例如,这个传奇:

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


推荐答案

这个非常受欢迎的信念,不过生成器本身与Promises或asy无关非同步功能。生成器只是通过将一些资源和责任委托给上层函数来实现可中断功能。

This very popular belief, however generators in itself have no relation to Promises or asynchronous functions. Generators is just about make interruptible function with delegating some resources and responsibility to upper level function.

如果 redux-saga ,有两个部分:独立的saga runner进程和调度程序(),由 sagaMiddleware推出。 run()命令和效果反应,将动作委托给主要传奇过程。

In case of redux-saga, there is two parts: independent saga runner process and scheduler (https://github.com/redux-saga/redux-saga/blob/master/src/internal/runSaga.js) , which is launched by sagaMiddleware.run() command, and effects reactions, which delegates actions into main saga process.

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

So, simplest process manager in ES6, which emulates redux-saga behavior, will be like that (very simplified):

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生成器等待promx,比如redux-saga?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-14 10:38