0
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 回调函数中建立了连接,我将对象存储在sessionStoragevia中,JSON但是当我在第二个的 AJAX 回调中使用它时,就会出现错误

TypeError: parsedConnection.sendMsg 不是函数

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

我的问题是:谁能告诉我如何通过 JSON 或任何其他方式来存储基于原型的对象来实现这一点?

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

更新

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

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

然后它停留

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

有什么输入吗?谢谢!

4

2 回答 2

0

很难确切地看到您在各个方面都在努力实现什么,但让我们假设:

  • 对于各种 DOM 元素,单击处理程序(委托给文档)将导致通过 socket.send() 发送异步派生数据。
  • 套接字将使用异步派生的 uri 进行初始化。
  • 插座应保持可用以立即重复使用。
  • 初始化套接字的数据将被缓存在本地存储中以供将来的会话使用。(存储套接字本身没有意义)。

此外,我们需要承认,如果不能立即重用套接字消耗的资源,那么它确实应该被处理掉。

整个策略异常复杂。通常可以接受每个会话执行一次 ajax 操作以获取 uri 的开销,就像每次需要创建套接字时一样。但是,编写具有所有所述特征的东西是一项有趣的练习。

这可能不是 100% 正确,但可能会给你一些想法,包括使用 Promise 来满足几个异步问题。开始 ...

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()and.getSocket()会简化到您可能会选择将剩余的内容滚动.getSocket().send().

于 2015-12-28T21:54:04.147 回答
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);

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

于 2015-12-27T10:15:21.333 回答