繁体   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