简体   繁体   English

Redux传奇:yield put在嵌套回调中不起作用

[英]Redux saga: yield put not working inside nested callback

const { payload: {loginType, email, password, notification, self} } = action;

  console.log("--TRY--");
  Firebase.login(loginType, { email, password })
    .catch(function(result) {
      const message =
        result && result.message ? result.message : 'Sorry Some error occurs';
      notification('error', message);
      self.setState({
        confirmLoading: false
      });
      isError = true;
    })
    .then(function(result) {
      if (isError) {
        return;
      }
      if (!result || result.message) {
        const message =
          result && result.message
            ? result.message
            : 'Sorry Some error occurs';
        notification('error', message);
        self.setState({
          confirmLoading: false
        });
      } else {
        self.setState({
          visible: false,
          confirmLoading: false
        });
        console.log("--RIGHT BEFORE I CHECK AUTH STATE--");

        //the following does NOT fire
        firebaseAuth().onAuthStateChanged(function*(user) {
              console.log("THE GENERATOR RUNS");
              if (user) {
                  console.log(user);
                  yield put({
                      type: actions.LOGIN_SUCCESS,
                      token: 'secret token',
                      profile: 'Profile'
                  });
                  yield put(push('/dashboard'));
              }
              else {
                  yield put({ type: actions.LOGIN_ERROR });
              }
          });
      }
  }); });

Hi. 你好 I'm currently working with redux saga for the first time. 我目前是第一次使用redux saga。 I've been trying to get yield put to fire in the callback of the firebaseAuth().onAuthStateChanged listener. 我一直在尝试在firebaseAuth()。onAuthStateChanged侦听器的回调中提高收益。 The yield keyword won't work in a function that is not an ES6 generator, so I added an asterisk to the callback but now it won't execute at all. yield关键字在不是ES6生成器的函数中不起作用,因此我在回调中添加了一个星号,但现在根本无法执行。 Would really appreciate any advice on the matter. 非常感谢您对此事的任何建议。

As you noticed, redux-saga effects can only be used within a generator function, and you cannot use a generator function as a regular function: calling a generator function only returns a special object. 如您所见,redux-saga效果只能在生成器函数中使用,并且不能将生成器函数用作常规函数:调用生成器函数只会返回一个特殊对象。

The right way to approach this is to use an eventChannel : it lets you connect your saga to a source of events external to the redux ecosystem. 解决此问题的正确方法是使用eventChannel :它使您可以将传奇连接到redux生态系统外部的事件源。

First create your eventChannel using the provided factory function: it hands you an emit function that you can use to emit events; 首先使用提供的工厂函数创建eventChannel :它为您提供了一个可以用于发出事件的emit函数; then consume these events using the take effect. 然后消耗使用这些事件take的作用。

import { eventChannel } from 'redux-saga';
import { cancelled, take } from 'redux-saga/effects';

// first create your eventChannel
const authEventsChannel = eventChannel( emit => {
  const unsubscribe = firebaseAuth().onAuthStateChanged( user => {
    emit({ user });
  });
  // return a function that can be used to unregister listeners when the saga is cancelled
  return unsubscribe;
});

// then monitor those events in your saga
try {
  while (true) {
    const { user } = yield take (authEventsChannel);
    // handle auth state
  }
} finally {
  // unregister listener if the saga was cancelled
  if (yield cancelled()) authEventsChannel.close();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM