在sessionStorage中保存基于JavaScript原型的对象?

时间:2015-12-27 09:55:58

标签: javascript jquery json ajax 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回调函数中建立连接,然后通过sessionStorage将对象存储在JSON中,但是当我在第二个AJAX回调中使用它时,错误即将来临

  

TypeError:parsedConnection.sendMsg不是函数

现在我明白可能是因为JSON可用于存储普通对象而不是基于原型的对象

我的问题是:任何人都可以通过JSON或其他任何方式告诉我如何存储基于原型的对象吗?

我不想使用eval。任何代码,参考将非常感激。谢谢!

更新

我按照@Dan Prince提到的那样做了,但是当我在sendMsg函数中使用时出现了一个新问题

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

然后它保持

  

InvalidStateError:尝试使用不是的对象,   或者不再可用

任何输入?谢谢!

2 个答案:

答案 0 :(得分:0)

你可能通过将原型存储为对象的属性来破解你自己的解决方案,然后在阅读之后用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);

这将以自然且可预测的方式重建正确的原型链。

答案 1 :(得分:0)

很难确切地看到你在各个方面都想要达到的目标,但让我们假设:

  • 对于各种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()剩余的内容滚动到.send()的范围内{1}}。