不使用数据库在 JavaScript 中保存数据
你刚刚写了一段很棒的 JavaScript 代码。但是,当运行进程停止,或者用户刷新时,所有这些有用的数据都会消失得无影无踪。
这是你嗎?
在进行原型设计或从事小型项目时,管理某些状态可能会很有帮助,而无需借助于不是为您试图解决的创意问题而设计的数据库解决方案。
我们将探索一些我刚开始接触 Web 时就希望知道的选项。我们将了解浏览器中的 JavaScript 和后端的 Node.js。我们还会了解一些使用本地文件系统的轻量级数据库。
Node.js
首先,使用 JSON 序列化数据并将其保存到磁盘。如果你之前没有使用过 JSON, MDN 文档中有一篇很棒的文章。
const fs = require('fs');
const users = {
'Bob': {
age: 25,
language: 'Python'
},
'Alice': {
age: 36,
language: 'Haskell'
}
}
fs.writeFile('users.json', JSON.stringify(users), (err) => {
// Catch this!
if (err) throw err;
console.log('Users saved!');
});
我们创建了用户对象,使用JSON#stringify将其转换为 JSON ,然后调用fs#writeFile。我们传入了文件名、序列化数据和一个箭头函数作为写入操作完成后的回调函数。在此期间,程序将继续执行代码。
您还可以使用此方法写入普通的序列化数据,只需传入任何可以转换为字符串的内容即可。如果您要存储文本数据,fs#appendFile可能会很有用。它使用几乎相同的 API,但会将数据发送到文件末尾,保留现有内容。
有一个同步选项fs#writeFileSync,但不建议使用,因为在写入操作完成之前,你的程序将无响应。在 JavaScript 中,你应该尽量避免使用永不阻塞。
如果您正在处理 CSV 文件,请使用久经考验的node-csv项目。
让我们使用fs#readFile将这些用户重新加载到我们的程序中。
fs.readFile('user.json', (err, data) => {
// Catch this!
if (err) throw err;
const loadedUsers = JSON.parse(data);
console.log(loadedUsers);
});
轻量级数据库
SQLite 使用本地文件作为数据库——它是我最喜欢的软件之一。它使我的许多小型项目能够以较低的维护成本和较少的部署麻烦运行。
以下是有关 SQLite 的一些事实:
- 该项目的测试代码和测试脚本的数量是其他代码的711 倍。
- 开发人员承诺至少到 2050 年保持其向后兼容。
- 它可以在飞机上、在 Android 上使用,而且您在今天阅读本文的过程中可能以某种方式与它进行过交互。
认真地说,SQLite 的测试方式是一次疯狂的旅程。
在 Node.js 中,我们通常使用sqlite3
npm 包。我将使用 Glitchhello-sqlite
模板中的一些代码,您无需账户即可试用和混编。
// hello-sqlite
var fs = require('fs');
var dbFile = './.data/sqlite.db'; // Our database file
var exists = fs.existsSync(dbFile); // Sync is okay since we're booting up
var sqlite3 = require('sqlite3').verbose(); // For long stack traces
var db = new sqlite3.Database(dbFile);
通过这个db
对象,我们可以与本地数据库进行交互,就像通过连接外部数据库一样。
我们可以创建表格。
db.run('CREATE TABLE Dreams (dream TEXT)');
插入数据(带有错误处理)。
db.run('INSERT INTO Dreams (dream) VALUES (?)', ['Well tested code'], function(err) {
if (err) {
console.error(err);
} else {
console.log('Dream saved!');
}
});
选择该数据。
db.all('SELECT * from Dreams', function(err, rows) {
console.log(JSON.stringify(rows));
});
您可能需要考虑序列化一些数据库查询。serialize () 函数中的每个命令都保证在下一个命令开始之前执行完成。sqlite3文档非常详尽。请留意 SQLite数据类型,因为它们可能与其他数据库略有不同。
如果连 SQLite 都觉得你的项目开销太大,可以考虑lowdb(也可以在 Glitch 上 remix)。lowdb 之所以令人兴奋,是因为它是一个由 Lodash 驱动的小型本地 JSON 数据库(支持 Node、Electron 和浏览器)。它不仅可以作为后端 JSON 文件的包装器,还提供了一个在浏览器中包装 localStorage 的 API。
从他们的例子来看:
import low from 'lowdb'
import LocalStorage from 'lowdb/adapters/LocalStorage'
const adapter = new LocalStorage('db')
const db = low(adapter)
db.defaults({ posts: [] })
.write()
// Data is automatically saved to localStorage
db.get('posts')
.push({ title: 'lowdb' })
.write()
浏览器
这将我们带到了前端。window #localStorage是在 HTTP cookie 中存储数据的现代解决方案 - MDN不再建议使用它来存储数据。
现在就让我们与它们交互吧。如果你使用的是桌面电脑,请打开你的开发者控制台(Chrome 上按 F12),看看 DEV 为你存储了什么:
for (const thing in localStorage) {
console.log(thing, localStorage.getItem(thing))
}
// Example of one thing:
// pusherTransportTLS {"timestamp":1559581571665,"transport":"ws","latency":543}
我们了解了 lowdb 如何与 localStorage 交互,但对于我们的小项目来说,直接与 API 交互可能更方便。像这样:
// As a script, or in console
localStorage.setItem('Author', 'Andrew') // returns undefined
localStorage.getItem('Author') // returns "Andrew"
localStorage.getItem('Unset key') // returns null
事情变得更简单了:你可以把它当作一个对象。不过,MDN 更推荐使用这个 API,而不是这个快捷方式。
console.log(localStorage['Author']); // prints "Andrew"
如果您不想永远将数据存储在用户的计算机上(可以使用 清除localStorage.clear()
但不要在 DEV 上运行它),您可能会对sessionStorage感兴趣,它具有几乎相同的 API,并且仅在用户在页面上时存储数据。
结束语
我读到过一些文章说国际空间站上某种程度上使用了 SQLite,但我找不到相关资料。我的未婚夫想让你知道 SQLite是一个数据库,而这篇文章的标题是错误的。
与 150 多名订阅我的关于编程和个人成长的新闻通讯的人一起!
我发布有关科技的推文@healeycodes。
文章来源:https://dev.to/healeycodes/ saving-data-in-javascript-without-a-database-22n