簡體   English   中英

將基於JavaScript原型的對象保存在sessionStorage中?

[英]Save JavaScript prototype based objects in sessionStorage?

var obj = { 
conn : null,
first : function(thisIdentity) {
    "use strict";
    var myObj = this;
    $(document).on('click', thisIdentity, function(e) {
    e.preventDefault();
    $.ajax ({ 
        url : some value,
        // other parameters
        success : function(data) {
            myObj.conn = new Connection(data.user_id, "127.0.0.1:80");
            sessionStorage.setItem('connection', JSON.stringify(myObj.conn));
           }
        });
   },
second : function(thisIdentity) {
    "use strict";
    var myObj = this;
    var conntn = sessionStorage.getItem('connection');
        $(document).on('click', thisIdentity, function(e) {
        e.preventDefault();
        $.ajax ({ 
            url : some value,
            // other parameters
            success : function(data) { 
            var parsedConnection = JSON.parse(conntn);
            parsedConnection.sendMsg(data.id, data.nid);
        }
      });
    }
};
var Connection = (function() {
    function Connection(uid, url) {
       this.uid = uid;
       this.open = false;
       this.socket = new WebSocket("ws://"+url);
       this.setupConnectionEvents();
    },
Connection.prototype = {
    sendMsg : function(id, nid) {
        alert("Working");
    },
    // other functions
    }
})();

因此,連接是在第一個的AJAX回調函數中進行的,我通過JSON將對象存儲在sessionStorage ,但是當我在第二個的AJAX回調中使用該對象時,就會出現錯誤

TypeError:parsedConnection.sendMsg不是函數

現在我知道這可能是因為JSON可用於存儲普通對象而不是基於原型的對象

我的問題是: 誰能告訴我如何通過JSON或任何其他方式存儲基於原型的對象?

我不想使用eval 任何代碼,參考將不勝感激。 謝謝!

更新

我像@Dan Prince提到的那樣做,但是出現了一個新問題,現在在sendMsg函數中使用

this.socket.send(JSON.stringify({
   action: 'message',
   rec: receiver,
   msg: message
}));

然后它留下來

InvalidStateError:嘗試使用一個不可用或不再可用的對象

有輸入嗎? 謝謝!

您可以通過將原型存儲為對象的屬性,然后在讀取對象后使用Object.create對其進行實例化,從而破解自己的解決方案,但是真正的問題是為什么首先要這樣做?

我建議在Connection的原型上編寫一個序列化方法,該方法僅公開基本信息(例如,對Web套接字進行序列化是沒有意義的)。

Connection.prototype.toJSON = function() {
  return JSON.stringify({
    uid: this.uid,
    url: this.url,
    open: this.open
  });
};

將連接對象保存到會話存儲時,請使用此方法。

myObj.conn = new Connection(data.user_id, "127.0.0.1:80");
sessionStorage.setItem('connection', myObj.conn.toJSON());

現在,每個保存的連接都具有調用構造函數和重新創建實例所需的最少數據量。

從會話存儲中加載連接時,請對其進行解析,然后將值傳遞回構造函數。

var json = sessionStorage.getItem('connection');
var data = JSON.parse(json);
var connection = new Connection(data.uid, data.url)

// ...
connection.sendMsg(data.id, data.nid);

這將以自然和可預測的方式重建正確的原型鏈。

很難確切地看到您在各個方面想要實現的目標,但讓我們假設:

  • 對於各種DOM元素,單擊處理程序(授權給文檔)將導致通過socket.send()發送異步派生的數據。
  • 套接字將使用異步派生的uri進行初始化。
  • 套接字應保持可供立即使用。
  • 初始化套接字所用的數據將緩存在本地存儲中,以供將來的會話使用。 (存儲套接字本身沒有任何意義)。

另外,我們需要承認,如果套接字重新使用不是立即進行的,則應該真正處理它消耗的資源。

整個策略異常復雜。 每個會話執行一次ajax操作以獲得uri的開銷通常會被接受,就像每次需要一個套接字時創建套接字一樣。 但是,寫具有所有規定特征的東西是一個有趣的練習。

這可能不是100%正確的,但可能會給您一些想法,包括使用promises來解決一些異步問題。 開始 ...

var obj = {
    conn: null,
    init: function(thisIdentity) {
        // It makes sense to attach the click handler only *once*, so let's assume this is an init function.
        "use strict";
        var myObj = this;
        $(document).on('click', thisIdentity, function(e) {
            e.preventDefault();
            $.ajax ({
                url : some value,
                // other parameters
            }).then(function(data) {
                myObj.send(JSON.stringify({
                    'id': data.id,
                    'nid': data.nid
                }));
            });
        });
    },
    send: function(data) {
        "use strict";
        var myObj = this;
        return myObj.getSocket().then(function(socket) {
            socket.send(data);
        }).then(function() {
            // by disposing in later event turn, a rapid series of send()s has at least a chance of using the same socket instance before it is closed.
            if(socket.bufferedAmount == 0) { // if the socket's send buffer is empty, then dispose of it.
                socket.close();
                myObj.conn = null;
            }
        });
    },
    getSocket: function() {
        "use strict";
        var myObj = this;
        //1. Test whether or not myObj.conn already exists ....
        if(!myObj.conn) {
            //2 .... if not, try to recreate from data stored in local storage ...
            var connectionData = sessionStorage.getItem('connectionData');
            if(connectionData) {
                myObj.conn = myObj.makeSocket(connectionData.user_id);
            } else {
                //3. ... if connectionData is null, perform ajax.
                myObj.conn = $.ajax({
                    url: some value,
                    // other parameters
                }).then(function(data) {
                    sessionStorage.setItem('connectionData', JSON.stringify(data));
                    return myObj.makeSocket(data.user_id);
                });
            }
        }
        return myObj.conn; // note: myObj.conn is a *promise* of a socket, not a socket.
    },
    makeSocket: function(uid) {
        "use strict";
        var myObj = this;
        var uri = "127.0.0.1:80"; // if this is invariant, it can be hard-coded here.

        // return a *promise* of a socket, that will be resolved when the socket's readystate becomes OPEN.
        return $.Deferred(function(dfrd) {
            var socket = new WebSocket("ws://" + uri);
            socket.uid = uid;
            socket.onopen = function() {
                myObj.setupConnectionEvents();// not too sure about this as we don't know what it does.
                dfrd.resolve(socket);
            };
        }).promise();
    }
};

在這種方案下,單擊處理程序或其他任何東西都可以調用obj.send()而不必擔心套接字的狀態。 如有必要, obj.send()將創建一個套接字。

如果您放棄在會話之間存儲數據的要求,那么.send().getSocket()會簡化到您可能選擇將.getSocket()剩余內容.getSocket().send()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM