Вы не сможете использовать yield put
внутри функции обратного вызова. Stomp js ничего не знает о сагах, поэтому он не знает, что он должен делать, когда ему предоставляется функция генератора.
Самый простой подход, хотя и не обязательно лучший, заключается в go непосредственно в сохраните в обратном вызове избыточное хранилище и отправьте действие, не задействуя избыточную сагу. Например:
import store from 'wherever you setup your store'
// ...
stomp.subscribe('/queue/data', message => {
const response = JSON.parse(message.body);
store.dispatch({
type: FETCH_SUCCESS,
payload: response.dataResponse,
});
});
Если вы хотите использовать более редуцированный сага-й подход, я бы рекомендовал заключить подписку в канал событий . Каналы событий используют API на основе обратного вызова и превращают его во что-то, с чем вы можете взаимодействовать, используя эффекты redux-saga, такие как take
Вот как вы можете создать канал событий:
import { eventChannel } from 'redux-saga';
function createChannel(token) {
return eventChannel(emitter => {
const socket = new SockJS(`${CONFIG.API_URL}/ws`);
const stomp = Stomp.over(socket);
stomp.connect(
{
Authorization: `Bearer ${token}`,
},
frame => {
stomp.subscribe('/queue/data', message => {
const response = JSON.parse(message.body);
emitter(response); // This is the value which will be made available to your saga
});
}
);
// Returning a cleanup function, to be called if the saga completes or is cancelled
return () => stomp.disconnect();
});
}
И тогда ты будешь использовать это так:
function* websocketSaga() {
const token = yield select(selectToken);
const channel = createChannel(token);
while (true) {
const response = yield take(channel);
yield put({
type: FETCH_SUCCESS,
payload: response.dataResponse,
});
}
}