Redux-сага и сокет подписки вызывают Uncaught TypeError: Преобразование круговой структуры в JSON
У меня возникают проблемы при подписке на канал socketcluster ( http://socketcluster.io/) при использовании генератора redux-saga в моем приложении чата. Серверная часть socketcluster настраивается таким образом, что любые сообщения сохраняются в базе данных, а затем публикуются в личном канале принимающего пользователя, который назван в честь идентификатора пользователя. Например, пользователь A имеет идентификатор "123abc" и будет подписываться на канал с именем "123abc" для своих сообщений в реальном времени.
Приведенный ниже код получает новые сообщения, которые публикуются в канале, но он выдает "TypeError: Преобразование циклической структуры в JSON" и отключает все мои другие генераторы redux-saga в приложении. Я закончил копаться в Chrome Devtools, и моя теория состоит в том, что это как-то связано с очередью, созданной в функции createChannel. Кроме того, я попытался вернуть отложенное обещание в функции subscribeToChannel, но это также вызвало ошибку циклического преобразования, я могу опубликовать этот код по запросу.
Сначала я сослался на этот ответ: /questions/1142231/kak-svyazat-sobyitiya-generiruemyie-sobyitiyami-v-redx-sagu/1142249#1142249 и это помогло мне получить приведенный ниже код, но я не могу найти аналогичные проблемы в Интернете. Также кое-что стоит отметить, я использую кластер сокета redux-сокета ( https://github.com/mattkrick/redux-socket-cluster) для синхронизации сокета и состояния, но я не думаю, что это корень проблема
sagas.js
export default function* root() {
yield [
fork(startSubscription),
]
}
function* startSubscription(getState) {
while (true) {
const {
userId
} = yield take(actions.SUBSCRIBE_TO_MY_CHANNEL);
yield call(monitorChangeEvents, subscribeToChannel(userId))
}
}
function* monitorChangeEvents(channel) {
while (true) {
const info = yield call(channel.take) // Blocks until the promise resolves
console.log(info)
}
}
function subscribeToChannel(channelName) {
const channel = createChannel();
const socket = socketCluster.connect(socketConfig);
const c = socket.subscribe(channelName);
c.watch(event => {
channel.put(event)
})
return channel;
}
function createChannel() {
const messageQueue = []
const resolveQueue = []
function put(msg) {
// anyone waiting for a message ?
if (resolveQueue.length) {
// deliver the message to the oldest one waiting (First In First Out)
const nextResolve = resolveQueue.shift()
nextResolve(msg)
} else {
// no one is waiting ? queue the event
messageQueue.push(msg)
}
}
// returns a Promise resolved with the next message
function take() {
// do we have queued messages ?
if (messageQueue.length) {
// deliver the oldest queued message
return Promise.resolve(messageQueue.shift())
} else {
// no queued messages ? queue the taker until a message arrives
return new Promise((resolve) => resolveQueue.push(resolve))
}
}
return {
take,
put
}
}
Спасибо за помощь!