我开发了一种用于将数据存储在LocalStorage中的Web技术游戏。 LocalStorage用作synchronous.To设置并从localstorage获取值
//设置localstorage中的值
localStorage.setItem('Key', "value");
//从localstorage
获取值var localValue = localStorage.getItem('Key');
localstorage有5MB的限制。在发挥一定程度后,本地存储完全填满。我需要在客户端进行大面积存储。
我的第一个问题是“解决这个问题的最佳方法是什么?”
为了解决上述问题,我找到了LargeLocalStorage。它是异步的。
//在LargeLocalStorage中设置值
storage.setContents('docKey', "the contents...").then(function() {alert('doc created/updated');});
//从LargeLocalStorage获取值
storage.getContents('myDoc').then(function(content){//content is value for particular key});
是否有任何方法可以使这些方法同步,因为我的所有代码都是根据同步localstorage。根据异步LargeLocalStorage更改整个逻辑需要花费大量时间。
我目前正尝试将localstorage的setItem和getItem方法覆盖为:
localStorage.__proto__.getItem = function(key) {
var returnVal;
storage.getContents(key).then(function(content) {
returnVal = content;
});
return returnVal;//it returns undefined
}
由于异步行为,上面覆盖方法返回未定义的值。
请使用上述方法帮助我获得价值同步。
提前致谢。
答案 0 :(得分:0)
好的,LocalStorage很安静,但是如果你想存储大量数据,我建议你看看 PouchDB ,这是 CouchDB ,一个NoSQL数据库。
Pouchdb使用 IndexedDB 作为其存储机制。因此,PouchDB在浏览器中运行,提供了速度。
我认为这对您的情况非常有帮助:)。
如果你有时间看一下我所做的这段代码:
数据库类
var Database = (function(){
var instance = undefined;
function Database(){
//Create new database Game
this.db = new PouchDB('Game');
//Listen for db changes, and fired show function
this.db.changes({
since: 'now',
live: true
}).on('change', this.show);
}
//Show function retrieve all docs, and add it to the html
Database.prototype.show = function(){
this.db
.allDocs({include_docs: true, descending: true})
.then(function(response){
var data = response.rows;
var preview = document.querySelector('.preview');
while (preview.firstChild) {
preview.removeChild(preview.firstChild);
}
data.forEach(function(elm){
var p = document.createElement('p');
p.innerHTML = elm.doc.title;
preview.appendChild(p);
});
});
}
//Add a doc to our database
Database.prototype.add = function(data){
this.db
.post(data)
.then(function(response){
console.log('Data added !');
}).catch(function(err){
console.log(err);
});
}
//Clean our database
Database.prototype.reset = function(){
var db = this.db;
//retrieve all docs
db.allDocs({include_docs:true, descending: true})
.then(function(response){
var rows = response.rows;
var docs = rows.map(function(elm){
return elm.doc;
});
//Create promises array
var promises = docs.map(function(elm){
//Return promise remove
return db.remove(elm._id, elm._rev);
});
//Resolve all promisein our array
Promise.all(promises).then(function(data){
console.log('Database Cleaned !');
});
});
}
return {
get: function(){
if (!instance){
instance = new Database();
}
return instance;
}
}
})();
采取一些行动
//Create a database
var DB = Database.get();
function add(){
var value = document.querySelector('#value').value;
var obj = {
title: value
};
//Add obj to our database
DB.add(obj);
}
function reset(){
//Reset our database
DB.reset();
}
<强> HTML 强>
<input type="text" name="name" id="value">
<button type="button" name="button" onclick="add()">add</button>
<button type="button" name="button" onclick="reset()">Destory database</button>
<div class="preview">
</div>
我认为 PouchDB 是一个非常好的东西,如果你有时间,可以自由测试它:)
答案 1 :(得分:0)
是否有任何方法可以使这些方法同步
没有。异步方法是异步的,因为它们是异步的。你不能在明天(或从现在起100ms)发生一些事情,而不是现在发生。
你真正想要的是一种编写异步代码的方法,使它看起来像同步代码。这将更具可读性,在您的情况下,将使您的代码更容易适应。
我们想以某种方式写出
A() . then(B);
as
A();
B();
并且意思相同:在执行B之前等待A完成。如果涉及变量或结果,那么我们希望能够写
A() . then(function(a) { return B(a+1); })
作为
var a = A();
B(a+1);
事实证明是的一种方法:异步函数。此功能绝不适用于所有环境,但很容易找到访问它的方法。要使用异步功能,我将关键字async
放在function
前面,然后使用特殊关键字await
。所以上面的代码只是:
async function foo() {
var a = await A();
await B(a+1);
}
要使其工作,请使用Babel转换代码,选择启用异步功能的选项。 Babel会将您的代码翻译成ES5,这是所有浏览器都知道如何解释的JavaScript。
上面的代码实际上会返回一个承诺,你可以挂起then
,或者在另一个异步函数中使用:
async function bar() {
await foo();
}
在您的具体案例中:
async function write(contents) {
await storage.setContents('docKey', contents);
alert('doc created/updated');
}
您可能想了解另一种方法。它使用“生成器”,它是ES6中一种特殊类型的函数,它“返回”一个值,但保持它们的状态,并且可以再次调用并在之间执行之后返回更多值。生成器是这样写的,在函数名后面加*
:
function* foo() {
yield 1;
yield 2;
}
以特殊方式调用此函数。首先,将其称为foo()
以创建一个名为 iterator 的东西,然后使用迭代器的next
方法获取下一个值。 (还有其他方法可以检索值序列,我们不会在这里讨论。)
这些生成器可用于编写所需的“异步但看起来同步”的代码,如下所示:
function* foo() {
var a = yield A();
yield B(a+1);
}
代码看起来与异步函数非常相似,但yield
替换await
。
但在这种情况下,与上述异步函数不同,我们需要某人或某事要求第一个值,然后等待yield
返回的承诺解析,然后要求第二个值,并且等等。这样做的代码不长,但有点复杂。有许多库和实用程序正是这样做的。例如,一个众所周知的名为co。使用co
,您可以编写与我之前显示的异步函数相同的代码,如下所示:
var foo = co.wrap(function* foo() {
var a = yield A();
yield B(a+1);
});
采用这种方法的一个原因是发电机是ES6的标准配置,并且比异步功能更广泛可用,这些功能正在考虑用于ES7。