Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在已经使用后重新分配变量?_Javascript_React Native - Fatal编程技术网

Javascript 在已经使用后重新分配变量?

Javascript 在已经使用后重新分配变量?,javascript,react-native,Javascript,React Native,我有一个我正在用React Native编写的应用程序。它是套接字的,我有一个控制所有套接字信息的文件 import {Alert, AppState} from 'react-native'; import store from '../store/store'; import {updateNotifications} from '../reducers/notifications'; import {setError, clearError} from '../reducers/error

我有一个我正在用React Native编写的应用程序。它是套接字的,我有一个控制所有套接字信息的文件

import {Alert, AppState} from 'react-native';
import store from '../store/store';
import {updateNotifications} from '../reducers/notifications';
import {setError, clearError} from '../reducers/error';
import {updateCurrentEvent, updateEventStatus, setCurrentEvent} from '../reducers/event_details';
import {setAlert} from '../reducers/alert';
import {ws_url} from '../api/urls'

let conn = new WebSocket(ws_url);

/*
handleSocketConnections handles any actions that require rerouting. The rest are passed off to handleOnMessage
This is being called from authLogin on componentDidMount. It would be ideal to only initialize a socket conn
when a user logs in somehow, but this package gets ran when a user opens the app, meaning there are socket 
connections that don't need to exist yet.
*/

function setAppStateHandler() {
    AppState.addEventListener('change', cstate => {
        if(cstate === 'active') {
            reconnect()
        }
    })
}
export const handleSocketConnections = (navigator, route) => {
    setAppStateHandler();

    conn.onmessage = e => {

        const state = store.getState();
        const msg = JSON.parse(e.data);
        const { type, payload, event_id } = msg;
        const { event } = state.event_details.event_details;

        if (type == "SET_EVENT_STATUS" && payload == "CLOSED" && event_id == event.event_id) {

            navigator.push(route)
            // store.dispatch(setAlert({
            //     message:"Event is closed, click to navigate to checkout."
            //     , scene: null
            // }))
            store.dispatch(updateEventStatus(payload));

        } else {

            handleOnMessage(msg, state)

        }
    }
}

export function reconnect() {
    //TODO: Fatal errors should redirect the mainNav to a fatal error screen. Not dismount the nav entirely, as it does now
    //and this should pop the error screen when it's fixed.
    let state = store.getState();

    conn = new WebSocket(ws_url);
    setTimeout(function () {
        if (conn.readyState == 1) {
            if (typeof state.event_details.event_details != 'undefined') {
                setSocketedEventInfo(state.event_details.event_details.event.event_id);
            }
            store.dispatch(clearError());
        } else {
            store.dispatch(setError('fatal',`Socket readyState should be 1 but it's ${conn.readyState}`))
        }
    }, 1000);
}

//Preform function on ES close.
conn.onclose = e => {
    console.log("Closing wsbidder, ", `${e.code} -- ${e.reason}`);
    //TODO: Set error here saying they need to restart the app. Maybe a 'reconnect' somehow?
    //Maybe set a store variable to socketErr and if null, all is good. Else, panic the app?

    //Use Case: Server is not started and user tries to connect to the app. String of e.message contains "Connection refused"
    store.dispatch(setError("fatal", `Socket onclose: ${e.code} -- ${e.reason}`))

};

conn.onerror = e => {
    console.log("Error at socket, ", e);
    store.dispatch(setError("fatal", `Socket onerror: ${e.message}`))
};

//Initialization function for websocket.
// conn.onopen = e => console.log("Opening wsbidder, ", e)

function handleOnMessage(msg, state) {

    switch (msg.type) {
        //These types come from the SocketWrappers on the server.
        //updateCurrentEvent should be filtering the event by event_id.
        case "EVENT_ITEMS":
            store.dispatch(updateCurrentEvent(
                msg.payload
                , state.user_info.uid
                , state.event_details.event_details.event.event_id));
            break;
        case "NOTIFICATIONS":
            //bug: this needs to filter notifications per event on the client-side.
            store.dispatch(updateNotifications(
                msg.payload
                , state.event_details.event_details.event.event_id
                , state.user_info.uid)
            );
            break;
        case "NOT_BIDDABLE":
            if (msg.event_id == state.event_details.event_details.event.event_id) {
                store.dispatch(updateEventStatus("CLOSED"));
            }
            break;
        case "PUSH_NOTIFICATION":
            const {title, message} = msg.payload;
            Alert.alert(title, message);
            break;
        default:
            console.warn(`Unrecognized socket action type: ${msg.type}`);
    }
}

//closes the socket connection and sends a reason to the server.
export const closeConn = reason => conn.close(null, reason);

export const setSocketedEventInfo = event_id => {
    //Gives the event ID to the socketed connection, which pulls end dates.
    const msg = {
        type: "UPDATE_EVENT_DETAILS"
        , payload: { event_id }
    }
    conn.send(JSON.stringify(msg));
}

export const createBid = (bid, cb) => {

    /*
     Expects:
     const new_bid = {
     item_id:    item.item_id,
     bid:        amount, //Storage keeps storing it as a string
     uid:        0, //Not needed here, but can't be null since the server wants an int.
     event_id, key, bidder
     };
     */

    const new_bid = {
        type: 'BID'
        , payload: bid
    };

    // Send this to the server socket
    conn.send(JSON.stringify(new_bid));

    //Returning the callback so the front-end knows to flip the card back over.
    return cb()
};
我知道有些代码是垃圾。除非你给出了真正的建议,我一直很乐意听从,否则没必要抨击它:-)

我遇到的问题是,当套接字死亡(conn变量)时,我无法重新初始化套接字并将其分配给该conn变量。我认为所有使用conn变量的函数都没有使用“新”变量,仍然使用“旧”变量

第9行--创建原始的

第28行——在handleSocketConnections函数中为conn对象创建onMessage函数,该函数在程序开始时在其他地方被调用

第57行--尝试在reconnect函数中为conn变量重新分配一个新连接,该函数在应用程序处于待机状态时运行(终止套接字连接)

第131行——通过重新连接函数正确调用它,再次将套接字连接到服务器

reconnect()函数运行正常-服务器使用所有正确的信息注册新连接,但应用程序似乎仍然处于一种奇怪的状态,没有连接错误(可能查看新连接???),但在连接上没有形成任何操作(可能查看旧连接?)


有什么想法吗?

如果必须启动替换webSocket连接,则需要重新运行连接到webSocket的所有代码(安装事件处理程序等)。因为它是一个新对象,所以旧的事件侦听器与新的webSocket对象没有关联

最简单的方法通常是创建一个
webSocketInit()
函数,当您第一次创建webSocket连接时,可以调用这两个函数,然后在需要用新连接替换它时再次调用。您可以将最新的webSocket对象传递给
webSocketInit()
,以便任何其他代码都可以看到新对象。如果单个代码块想知道旧代码块何时关闭,它们可以自己注册onclose


还有更多事件驱动的方法可以做到这一点,方法是创建一个EventEmitter,每当webSocket被替换时都会收到通知,如果单个代码块希望收到该事件的通知,则可以订阅该事件。

您的代码确实应该发布在此处。更改了问题,添加了代码。您是对的,
onclose()
onerror()
函数只绑定到最初创建的连接。每次创建新连接时,都必须重新分配这些。您可以通过将connection maker代码包装到自己的实用程序函数中来实现这一点。这会稍微澄清一些问题,但我正在尝试了解如何确保导出的连接使用新的连接对象。例如,“createBid”函数。@Nathanaland-您不需要使用
webSocketInit()
函数来调用更新
conn
变量
createBid()
所使用的内容吗?