[英]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可用於存儲普通對象而不是基於原型的對象 。
我不想使用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);
這將以自然和可預測的方式重建正確的原型鏈。
很難確切地看到您在各個方面想要實現的目標,但讓我們假設:
另外,我們需要承認,如果套接字重新使用不是立即進行的,則應該真正處理它消耗的資源。
整個策略異常復雜。 每個會話執行一次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.