Redux / saga: Как запустить действие (поместить) в обратный вызов без каналов (используйте sagas как обычные функции генератора) - PullRequest
0 голосов
/ 29 января 2019

Я ищу способ запустить действие изнутри обратного вызова.Я знаю, что это невозможно по умолчанию, но я ищу способ обойти.Каналы - плохое решение в моем случае (пока я вижу это).

Библиотека, которую я использую, является Reaction-native-ble-plx .В этой библиотеке есть функция для запуска сканирования: startDeviceScan(UUIDs, options, listener).

Чтобы сохранить это в чистоте, я хочу отключить сканирование начала / остановки от слушателя (следовательно, каналы не обсуждаются).

Раньше у меня было такое решение:

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

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

Проблема в том, что это связывает канал с началом и остановкой сканирования.Что заставляет вас подключать множество саг, потому что вам нужно запустить и остановить сканирование с помощью логики приложения (отменить канал, выполнить настройку заново, запустить новую сагу для прослушивания нового канала и т. Д.)

Что яимел в виду использование саг в качестве обычных функций генератора:

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

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

Таким образом, сага о прослушивании действий с найденным устройством может просто продолжаться.Но, хотя пут выполнен правильно, ни один дубль никогда не получает действие, которое предполагает, что пут не работает без саги-логики за кулисами.

Кто-то знает об этом больше?Или у кого-то есть альтернативный подход для реализации этого?

1 Ответ

0 голосов
/ 29 января 2019

Мне удалось решить проблему с помощью 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));
};

Работает как шарм =)

...