Redux/saga:如何在没有通道的回调中触发一个动作(放置)(使用 sagas 作为普通生成器函数)

Redux/saga: How to fire an action (put) inside a callback without channels (use sagas as normal generator functions)

我正在寻找一种从回调内部触发操作的方法。我知道默认情况下这是不可能的,但我正在寻找解决方法。就我而言,渠道是一个糟糕的解决方案(到目前为止我看到了)。

我使用的库是react-native-ble-plx。在那个库中,有一个开始扫描的函数:startDeviceScan(UUIDs, options, listener).

为了保持清洁,我想断开 start/stop 扫描与侦听器的连接(因此频道不在考虑范围之内)。

在我有这个解决方案之前:

const onScanChannel = () => eventChannel(emit => {
  BleService.startDeviceScan(..., ..., (peripheral) => {
      emit(peripheral);
    }
  );

  return () => {BleService.stopScan();}
});

问题是这将通道与扫描的开始和停止联系起来。这会导致您连接很多传奇,因为您需要从应用程序逻辑开始和停止扫描(取消频道、重新设置、开始新传奇以收听新频道等)

我的想法是将 sagas 用作普通生成器函数:

const startScanSaga = function* () {
  BleService.scan(..., ..., (peripheral) => {
    const generator = deviceFoundHandler(peripheral);
    generator.next();
    generator.next();
  });
};

const deviceFoundHandler = function* (peripheral) {
  yield put(actions.deviceFound(peripheral));
};

这样,监听找到的设备动作的 saga 就可以保持 运行。但是,尽管 put 已正确执行,但没有任何 take 会收到该操作,这表明如果没有幕后的 saga-logic,put 将无法工作。

有人知道更多吗?或者有人有其他方法可以实现这一点吗?

我使用 middleware.run(saga, ...args) 解决了这个问题。

我需要导出 sagaMiddleWare:export const sagaMiddleware = createSagaMiddleware();

import {sagaMiddleware} from '.../file-where-sagaMiddleWare-is-exported';

const startScanSaga = function* () {
  BleService.scan((peripheral) => {
    sagaMiddleware.run(deviceFoundHandler, peripheral);
  });
};

const deviceFoundHandler = function* (peripheral) {
  yield put(actions.deviceFound(peripheral));
};

工作起来很有魅力=)