Redux-saga和套接字订阅导致Uncaught TypeError:将循环结构转换为JSON

时间:2016-06-10 09:32:57

标签: sockets redux redux-saga socketcluster

在聊天应用中使用redux-saga生成器时,我无法订阅套接字集群(http://socketcluster.io/)频道。套接字集后端的设置方式是将任何消息保存在数据库中,然后发布到接收用户的个人频道,该频道以用户的ID命名。例如,用户A的ID为“123abc”。并订阅名为' 123abc'对于他们的实时消息。

下面的代码确实会收到发布到频道的新消息,但它会抛出一个" TypeError:将循环结构转换为JSON"在应用程序中onload并打破我所有的其他redux-saga生成器。我已经完成了挖掘Chrome Devtools的工作,我的理论是它与createChannel函数中创建的队列有关。另外,我尝试在subscribeToChannel函数中返回延迟的promise,但这也导致了循环转换错误,我可以根据请求发布该代码。

我首先提到了这个答案:https://stackoverflow.com/a/35288877/5068616它帮助我获得了以下代码,但我在互联网上找不到任何类似的问题。还有一点需要注意,我正在使用redux-socket-cluster(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
    }
}

感谢您的帮助!

0 个答案:

没有答案