更新したら自動で保存されるオブジェクトのサンプル
データを更新したら自動でファイルに保存する処理のサンプル 主な動作としては起動時に1回読み込んだデータを元に、更新されたら上書き保存していくもの
つまり起動後に別の方法で変更を加えても読み込まれることはなく、無視される
1つのファイルに対して複数回実行するのも厳禁
それなりに長いから別ファイルで保存して読み込んで使うのがおすすめyuta0801.icon
Promise.allで同時にオブジェクト変更するとファイルが壊れます。
JSONがぐちゃぐちゃになる。
ひとまず同時に保存しないように修正したyuta0801.icon
崩れなくなった!InkoHX.icon
使い方
code:js
!(async () => {
const data1 = await dataStore('./data1.json')
data1.foo = 1 // data1.jsonが自動的に更新される
// 第2引数でデフォルト(ファイルが無かったら作成されるデータ)の値を指定する(指定しないと{}になる)
const data2 = await dataStore('./data2.json', [])
data2.push(1)
})()
コード
code:js
const DeepProxy = require('proxy-deep')
const fs = require('fs').promises
const { dirname } = require('path')
const mkdirp = require('mkdirp')
const dataStore = async (path, _default = {}) => {
const data = await fs
.readFile(path)
.then(file => JSON.parse(file))
.catch(async () => {
await mkdirp(dirname(path))
await fs.writeFile(path, JSON.stringify(_default, null, 2))
return _default
})
const save = debounce(data => fs.writeFile(path, data), 10)
return new DeepProxy(data, {
get(target, key, receiver) {
const val = Reflect.get(target, key, receiver)
if (typeof val === 'object' && val !== null) {
return this.nest(val)
} else {
return val
}
},
async set(target, key, value, receiver) {
Reflect.set(target, key, value, receiver)
save(JSON.stringify(this.rootTarget, null, 2))
return true
},
})
}
const debounce = (fn, interval) => {
let timerId
return (...args) => {
clearTimeout(timerId)
timerId = setTimeout(() => fn(...args), interval)
}
}
使用例