在Meteor.call之后在Saga Watcher中调度动作

时间:2019-09-12 13:29:29

标签: reactjs meteor redux redux-saga

我想在Meteor.call回调中调度动作。

我试图将生成器函数作为回调传递,但不起作用。

function* createRegistrationField(action: CreateRegistrationFieldRequest) {
  yield call(function* () {
    yield put(CreateRegistrationFieldRequestRunningAction());
  });

  const { type } = action.payload;

  const callBack = function*(error, _id) {
    console.log("callback called");

    yield put(RegistrationFieldCreatedAction(type, _id));
  };

  Meteor.call("registerFormFields.insert", { type }, callBack);
};


export function* watchCreateRegistrationField() {
  yield takeLatest(CREATE_REGISTRATION_FIELD_REQUEST, createRegistrationField);
};

registerFormFields.insert看起来

  Meteor.methods({
    "registerFormFields.insert" (data: object) {
      return RegisterFormFields.insert(data);
    },
    "registerFormFields.list" () {
      return RegisterFormFields.find({}).fetch();
    }
  });

1 个答案:

答案 0 :(得分:1)

我找到了解决方案。

在redux-saga中,我们有eventChannel

下面是我如何做的例子。

import { eventChannel, END } from "redux-saga";

function createRegistrationFieldChannel(type: string) {
  return eventChannel(emitter => {
    Meteor.call("registerFormFields.insert", { type }, (error, _id) => {
      if (error) {
        emitter({ error });
        emitter(END);
      }

      emitter({ _id });
      emitter(END);
    });

    return () => {};
  });
}

function* createRegistrationField(action: CreateRegistrationFieldRequest) {
  yield call(function*() {
    yield put(CreateRegistrationFieldRequestRunningAction());
  });

  const { type } = action.payload;

  const channel = yield call(createRegistrationFieldChannel, type);

  try {
    while (true) {
      const { error = null, _id } = yield take(channel);

      if (error) {
      } else {
        yield put(RegistrationFieldCreatedAction(type, _id));
      }
    }
  } catch (err) {
    console.log(err);
  }
}

export function* watchCreateRegistrationField() {
  yield takeLatest(CREATE_REGISTRATION_FIELD_REQUEST, createRegistrationField);
}