我正在寻找一种从回调内部触发操作的方法。我知道默认情况下这是不可能的,但我正在寻找解决方法。就我而言, channel 是一个糟糕的解决方案(到目前为止我认为是这样)。
我使用的库是react-native-ble-plx 。在该库中,有一个开始扫描的函数:startDeviceScan(UUIDs, options,listener)
。
为了保持干净,我想断开监听器的开始/停止扫描(因此 channel 是不可能的)。
在我找到这个解决方案之前:
const onScanChannel = () => eventChannel(emit => {
BleService.startDeviceScan(..., ..., (peripheral) => {
emit(peripheral);
}
);
return () => {BleService.stopScan();}
});
问题在于这将 channel 与扫描的开始和停止连接起来。这会导致您连接很多 sagas,因为您需要从应用程序逻辑启动和停止扫描(取消 channel 、重新设置、启动新的 saga 来监听新 channel 等)
我的想法是使用 sagas 作为普通的生成器函数:
const startScanSaga = function* () {
BleService.scan(..., ..., (peripheral) => {
const generator = deviceFoundHandler(peripheral);
generator.next();
generator.next();
});
};
const deviceFoundHandler = function* (peripheral) {
yield put(actions.deviceFound(peripheral));
};
这样,监听发现设备操作的传奇就可以继续运行。但是,尽管 put 执行正确,但没有任何 take 接收到该操作,这表明如果没有幕后的 saga 逻辑, 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));
};
工作起来就像一个魅力=)
关于react-native - 终极版/传奇 : How to fire an action (put) inside a callback without channels (use sagas as normal generator functions),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54421872/