@less-is-more/less-js 1.5.0-1 → 1.5.0-11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/cache.js +22 -15
- package/src/nas.js +95 -56
- package/test/test-nas.js +57 -36
package/package.json
CHANGED
package/src/cache.js
CHANGED
|
@@ -40,10 +40,17 @@ module.exports = class Cache {
|
|
|
40
40
|
* @param {*} args 直接传arguments,用于拼接缓存key
|
|
41
41
|
* @param {function} fn 没有缓存的实现
|
|
42
42
|
* @param {boolean} zip 是否压缩
|
|
43
|
-
* @param {boolean}
|
|
43
|
+
* @param {boolean} useNas 是否使用Nas缓存
|
|
44
44
|
* @returns 优先返回对象
|
|
45
45
|
*/
|
|
46
|
-
static async auto(
|
|
46
|
+
static async auto(
|
|
47
|
+
keyPrefix,
|
|
48
|
+
timeSecond,
|
|
49
|
+
args,
|
|
50
|
+
fn,
|
|
51
|
+
zip = false,
|
|
52
|
+
useNas = false
|
|
53
|
+
) {
|
|
47
54
|
let fullKey = keyPrefix;
|
|
48
55
|
for (let i = 0; i < args.length; i++) {
|
|
49
56
|
fullKey += ":" + args[i].toString();
|
|
@@ -52,7 +59,7 @@ module.exports = class Cache {
|
|
|
52
59
|
let savedData = Cache._getLocal(fullKey);
|
|
53
60
|
let hasLocal = false;
|
|
54
61
|
if (Param.isBlank(savedData)) {
|
|
55
|
-
if (
|
|
62
|
+
if (useNas) {
|
|
56
63
|
savedData = Nas.get(fullKey);
|
|
57
64
|
} else {
|
|
58
65
|
savedData = await Redis.exec("get", fullKey);
|
|
@@ -67,29 +74,29 @@ module.exports = class Cache {
|
|
|
67
74
|
if (savedData == null) {
|
|
68
75
|
let result = await fn();
|
|
69
76
|
if (!Param.isBlank(result)) {
|
|
70
|
-
let
|
|
77
|
+
let saveContent = "";
|
|
71
78
|
// 处理JSON
|
|
72
79
|
if (result instanceof Object) {
|
|
73
80
|
if (result.success === false) {
|
|
74
81
|
console.log("Do not cache fail result");
|
|
75
82
|
} else {
|
|
76
|
-
|
|
83
|
+
saveContent = JSON.stringify(result);
|
|
77
84
|
}
|
|
78
85
|
} else {
|
|
79
|
-
|
|
86
|
+
saveContent = result.toString();
|
|
80
87
|
}
|
|
81
|
-
if (
|
|
82
|
-
if (Cache._needZip(
|
|
83
|
-
|
|
88
|
+
if (saveContent != "") {
|
|
89
|
+
if (Cache._needZip(saveContent, zip)) {
|
|
90
|
+
saveContent = Cache._zip(saveContent);
|
|
84
91
|
}
|
|
85
|
-
if (
|
|
86
|
-
Nas.set(fullKey,
|
|
92
|
+
if (useNas) {
|
|
93
|
+
Nas.set(fullKey, saveContent, timeSecond);
|
|
87
94
|
} else {
|
|
88
|
-
await Redis.exec("setex", fullKey, timeSecond + "",
|
|
95
|
+
await Redis.exec("setex", fullKey, timeSecond + "", saveContent);
|
|
89
96
|
}
|
|
90
97
|
|
|
91
98
|
// 本地缓存1分钟
|
|
92
|
-
Cache._setLocal(fullKey,
|
|
99
|
+
Cache._setLocal(fullKey, saveContent, 60000);
|
|
93
100
|
}
|
|
94
101
|
return result;
|
|
95
102
|
}
|
|
@@ -97,9 +104,9 @@ module.exports = class Cache {
|
|
|
97
104
|
console.log("Found cache" + (hasLocal ? " local" : ""), fullKey);
|
|
98
105
|
savedData = Cache._unzip(savedData);
|
|
99
106
|
// 优先转成json
|
|
100
|
-
|
|
107
|
+
try {
|
|
101
108
|
return JSON.parse(savedData);
|
|
102
|
-
}
|
|
109
|
+
} catch (e) {
|
|
103
110
|
return savedData;
|
|
104
111
|
}
|
|
105
112
|
}
|
package/src/nas.js
CHANGED
|
@@ -8,20 +8,23 @@ const os = require("os");
|
|
|
8
8
|
* 适用于多服务器共享NAS存储
|
|
9
9
|
*/
|
|
10
10
|
class Nas {
|
|
11
|
-
|
|
11
|
+
static _getCacheDir() {
|
|
12
|
+
let cacheDir = null;
|
|
13
|
+
|
|
12
14
|
// 如果提供了缓存目录参数,则使用该目录,否则使用默认目录
|
|
13
15
|
const defaultCacheDir = path.join(os.tmpdir(), "cache");
|
|
14
|
-
|
|
16
|
+
cacheDir =
|
|
15
17
|
cacheDir || (fs.existsSync("/cache") ? "/cache" : defaultCacheDir);
|
|
16
18
|
|
|
17
19
|
// 确保缓存目录存在
|
|
18
20
|
try {
|
|
19
|
-
if (!fs.existsSync(
|
|
20
|
-
fs.mkdirSync(
|
|
21
|
+
if (!fs.existsSync(cacheDir)) {
|
|
22
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
21
23
|
}
|
|
22
24
|
} catch (e) {
|
|
23
|
-
console.error("创建缓存目录失败:",
|
|
25
|
+
console.error("创建缓存目录失败:", cacheDir, e);
|
|
24
26
|
}
|
|
27
|
+
return cacheDir;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
/**
|
|
@@ -29,8 +32,8 @@ class Nas {
|
|
|
29
32
|
* @param {string} key - 缓存键
|
|
30
33
|
* @returns {any} 缓存值,如果过期或不存在则返回null
|
|
31
34
|
*/
|
|
32
|
-
get(key) {
|
|
33
|
-
return
|
|
35
|
+
static get(key) {
|
|
36
|
+
return Nas._loadFromDisk(key);
|
|
34
37
|
}
|
|
35
38
|
|
|
36
39
|
/**
|
|
@@ -39,8 +42,8 @@ class Nas {
|
|
|
39
42
|
* @param {any} defaultValue - 默认值
|
|
40
43
|
* @returns {any} 缓存值或默认值
|
|
41
44
|
*/
|
|
42
|
-
getOrDefault(key, defaultValue) {
|
|
43
|
-
const value =
|
|
45
|
+
static getOrDefault(key, defaultValue) {
|
|
46
|
+
const value = Nas.get(key);
|
|
44
47
|
return value !== null ? value : defaultValue;
|
|
45
48
|
}
|
|
46
49
|
|
|
@@ -50,9 +53,9 @@ class Nas {
|
|
|
50
53
|
* @param {any} value - 缓存值
|
|
51
54
|
* @param {number} timeout - 超时时间(秒),-1表示永不过期
|
|
52
55
|
*/
|
|
53
|
-
set(key, value, timeout = -1) {
|
|
56
|
+
static set(key, value, timeout = -1) {
|
|
54
57
|
const expireTime = timeout === -1 ? -1 : Date.now() + timeout * 1000;
|
|
55
|
-
|
|
58
|
+
Nas._saveToDisk(key, value, expireTime);
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
/**
|
|
@@ -60,24 +63,16 @@ class Nas {
|
|
|
60
63
|
* @param {string} key - 缓存键
|
|
61
64
|
* @returns {boolean} 是否存在且未过期
|
|
62
65
|
*/
|
|
63
|
-
exists(key) {
|
|
64
|
-
return
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* 获取缓存目录路径
|
|
69
|
-
* @returns {string} 缓存目录路径
|
|
70
|
-
*/
|
|
71
|
-
getCacheDir() {
|
|
72
|
-
return this.cacheDir;
|
|
66
|
+
static exists(key) {
|
|
67
|
+
return Nas.get(key) !== null;
|
|
73
68
|
}
|
|
74
69
|
|
|
75
70
|
/**
|
|
76
71
|
* 删除指定的缓存项
|
|
77
72
|
* @param {string} key - 缓存键
|
|
78
73
|
*/
|
|
79
|
-
del(key) {
|
|
80
|
-
|
|
74
|
+
static del(key) {
|
|
75
|
+
Nas._deleteCacheFile(key);
|
|
81
76
|
}
|
|
82
77
|
|
|
83
78
|
/**
|
|
@@ -85,8 +80,8 @@ class Nas {
|
|
|
85
80
|
* @param {string} key - 缓存键
|
|
86
81
|
* @returns {any} 缓存值,如果过期或不存在则返回null
|
|
87
82
|
*/
|
|
88
|
-
|
|
89
|
-
const filePath =
|
|
83
|
+
static _loadFromDisk(key) {
|
|
84
|
+
const filePath = Nas._getFilePath(key);
|
|
90
85
|
|
|
91
86
|
try {
|
|
92
87
|
if (!fs.existsSync(filePath)) {
|
|
@@ -94,7 +89,13 @@ class Nas {
|
|
|
94
89
|
}
|
|
95
90
|
|
|
96
91
|
// 读取缓存文件
|
|
97
|
-
|
|
92
|
+
let content;
|
|
93
|
+
try {
|
|
94
|
+
content = fs.readFileSync(filePath, "utf8");
|
|
95
|
+
} catch (e) {
|
|
96
|
+
console.warn("读取缓存文件失败:", filePath, e);
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
98
99
|
const lines = content.split("\n");
|
|
99
100
|
|
|
100
101
|
if (lines.length >= 2) {
|
|
@@ -106,10 +107,14 @@ class Nas {
|
|
|
106
107
|
if (!isNaN(expireTime)) {
|
|
107
108
|
if (expireTime === -1 || Date.now() < expireTime) {
|
|
108
109
|
// 文件未过期,返回值
|
|
109
|
-
|
|
110
|
+
let valueStr = Buffer.from(value, "base64").toString("utf8");
|
|
111
|
+
try {
|
|
112
|
+
return JSON.parse(valueStr);
|
|
113
|
+
} catch (e) {
|
|
114
|
+
// 如果解析JSON失败,则返回原始字符串
|
|
115
|
+
return valueStr;
|
|
116
|
+
}
|
|
110
117
|
} else {
|
|
111
|
-
// 文件已过期,删除文件
|
|
112
|
-
this.deleteCacheFile(key);
|
|
113
118
|
return null;
|
|
114
119
|
}
|
|
115
120
|
}
|
|
@@ -127,17 +132,32 @@ class Nas {
|
|
|
127
132
|
* @param {any} value - 缓存值
|
|
128
133
|
* @param {number} expireTime - 过期时间戳,-1表示永不过期
|
|
129
134
|
*/
|
|
130
|
-
|
|
135
|
+
static _saveToDisk(key, value, expireTime) {
|
|
131
136
|
// 将值转换为字符串,如果是对象则转换为JSON字符串
|
|
132
|
-
const
|
|
133
|
-
const
|
|
137
|
+
const valueStr = typeof value === "object" ? JSON.stringify(value) : value;
|
|
138
|
+
const content = Buffer.from(valueStr, "utf8").toString("base64");
|
|
139
|
+
const filePath = Nas._getFilePath(key);
|
|
134
140
|
|
|
135
141
|
try {
|
|
142
|
+
// 创建临时文件名,避免写入过程中的并发问题
|
|
143
|
+
const timestamp = Date.now();
|
|
144
|
+
const randomSuffix = Math.random().toFixed(4) * 10000;
|
|
145
|
+
const tempFilePath = `${filePath}.tmp.${timestamp}.${randomSuffix}`;
|
|
136
146
|
// 写入过期时间戳和值,用换行符分隔
|
|
137
147
|
const fileContent = `${expireTime}\n${content}`;
|
|
138
|
-
fs.writeFileSync(
|
|
148
|
+
fs.writeFileSync(tempFilePath, fileContent, "utf8");
|
|
149
|
+
// 原子性地替换原文件
|
|
150
|
+
fs.renameSync(tempFilePath, filePath);
|
|
139
151
|
} catch (e) {
|
|
140
152
|
console.error("保存缓存文件失败:", filePath, e);
|
|
153
|
+
// 如果临时文件创建失败,清理临时文件
|
|
154
|
+
try {
|
|
155
|
+
if (fs.existsSync(tempFilePath)) {
|
|
156
|
+
fs.unlinkSync(tempFilePath);
|
|
157
|
+
}
|
|
158
|
+
} catch (cleanupError) {
|
|
159
|
+
// 忽略清理错误
|
|
160
|
+
}
|
|
141
161
|
}
|
|
142
162
|
}
|
|
143
163
|
|
|
@@ -145,8 +165,8 @@ class Nas {
|
|
|
145
165
|
* 删除缓存文件
|
|
146
166
|
* @param {string} key - 缓存键
|
|
147
167
|
*/
|
|
148
|
-
|
|
149
|
-
const filePath =
|
|
168
|
+
static _deleteCacheFile(key) {
|
|
169
|
+
const filePath = Nas._getFilePath(key);
|
|
150
170
|
try {
|
|
151
171
|
if (fs.existsSync(filePath)) {
|
|
152
172
|
fs.unlinkSync(filePath);
|
|
@@ -161,26 +181,47 @@ class Nas {
|
|
|
161
181
|
* @param {string} key - 缓存键
|
|
162
182
|
* @returns {string} 文件路径
|
|
163
183
|
*/
|
|
164
|
-
|
|
184
|
+
static _getFilePath(key) {
|
|
165
185
|
// 为键生成安全的文件名
|
|
166
186
|
const safeKey = key.replace(/[^a-zA-Z0-9-_.]/g, "_");
|
|
167
|
-
return path.join(
|
|
187
|
+
return path.join(Nas._getCacheDir(), `${safeKey}.cache`);
|
|
168
188
|
}
|
|
169
189
|
|
|
170
190
|
/**
|
|
171
|
-
*
|
|
191
|
+
* 清空所有过期缓存
|
|
172
192
|
*/
|
|
173
|
-
flushAll() {
|
|
193
|
+
static flushAll() {
|
|
174
194
|
try {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
fs.
|
|
178
|
-
) {
|
|
179
|
-
const files = fs.readdirSync(this.cacheDir);
|
|
195
|
+
const cacheDir = Nas._getCacheDir();
|
|
196
|
+
if (fs.existsSync(cacheDir) && fs.statSync(cacheDir).isDirectory()) {
|
|
197
|
+
const files = fs.readdirSync(cacheDir);
|
|
180
198
|
for (const file of files) {
|
|
181
199
|
if (file.endsWith(".cache")) {
|
|
182
|
-
const filePath = path.join(
|
|
183
|
-
|
|
200
|
+
const filePath = path.join(cacheDir, file);
|
|
201
|
+
// 检查文件是否过期超过一分钟,如果超过则删除
|
|
202
|
+
try {
|
|
203
|
+
if (fs.existsSync(filePath)) {
|
|
204
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
205
|
+
const lines = content.split("\n");
|
|
206
|
+
|
|
207
|
+
if (lines.length >= 1) {
|
|
208
|
+
const expireTimeString = lines[0];
|
|
209
|
+
const expireTime = parseInt(expireTimeString);
|
|
210
|
+
|
|
211
|
+
if (
|
|
212
|
+
!isNaN(expireTime) &&
|
|
213
|
+
expireTime !== -1 &&
|
|
214
|
+
// 仅删除过期超过一分钟的文件
|
|
215
|
+
Date.now() > expireTime + 60 * 1000
|
|
216
|
+
) {
|
|
217
|
+
console.log("删除过期缓存文件:", filePath);
|
|
218
|
+
fs.unlinkSync(filePath);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
} catch (e) {
|
|
223
|
+
console.warn("检查缓存文件过期时间失败:", filePath, e);
|
|
224
|
+
}
|
|
184
225
|
}
|
|
185
226
|
}
|
|
186
227
|
}
|
|
@@ -194,11 +235,11 @@ class Nas {
|
|
|
194
235
|
* @param {string} key - 缓存键
|
|
195
236
|
* @param {number} second - 过期时间(秒)
|
|
196
237
|
*/
|
|
197
|
-
expire(key, second) {
|
|
198
|
-
const currentValue =
|
|
238
|
+
static expire(key, second) {
|
|
239
|
+
const currentValue = Nas.get(key);
|
|
199
240
|
if (currentValue !== null) {
|
|
200
241
|
const expireTime = Date.now() + second * 1000;
|
|
201
|
-
|
|
242
|
+
Nas._saveToDisk(key, currentValue, expireTime);
|
|
202
243
|
}
|
|
203
244
|
}
|
|
204
245
|
|
|
@@ -207,10 +248,10 @@ class Nas {
|
|
|
207
248
|
* @param {string} key - 缓存键
|
|
208
249
|
* @param {number} expireTime - 过期时间戳(毫秒)
|
|
209
250
|
*/
|
|
210
|
-
expireAt(key, expireTime) {
|
|
211
|
-
const currentValue =
|
|
251
|
+
static expireAt(key, expireTime) {
|
|
252
|
+
const currentValue = Nas.get(key);
|
|
212
253
|
if (currentValue !== null) {
|
|
213
|
-
|
|
254
|
+
Nas._saveToDisk(key, currentValue, expireTime);
|
|
214
255
|
}
|
|
215
256
|
}
|
|
216
257
|
|
|
@@ -219,8 +260,8 @@ class Nas {
|
|
|
219
260
|
* @param {string} key - 缓存键
|
|
220
261
|
* @returns {number} 剩余生存时间(秒),如果不存在或已过期则返回-1
|
|
221
262
|
*/
|
|
222
|
-
ttl(key) {
|
|
223
|
-
const filePath =
|
|
263
|
+
static ttl(key) {
|
|
264
|
+
const filePath = Nas._getFilePath(key);
|
|
224
265
|
|
|
225
266
|
try {
|
|
226
267
|
if (!fs.existsSync(filePath)) {
|
|
@@ -241,8 +282,6 @@ class Nas {
|
|
|
241
282
|
const remainingTime = Math.floor((expireTime - Date.now()) / 1000);
|
|
242
283
|
return Math.max(0, remainingTime); // 确保返回非负值
|
|
243
284
|
} else {
|
|
244
|
-
// 文件已过期,删除文件
|
|
245
|
-
this.deleteCacheFile(key);
|
|
246
285
|
return -1;
|
|
247
286
|
}
|
|
248
287
|
}
|
package/test/test-nas.js
CHANGED
|
@@ -2,100 +2,121 @@ const Nas = require("../src/nas");
|
|
|
2
2
|
const assert = require("assert");
|
|
3
3
|
|
|
4
4
|
describe("Nas Class Tests", function () {
|
|
5
|
-
let nas = new Nas();
|
|
6
|
-
|
|
7
5
|
it("should set and get a string value", function () {
|
|
8
|
-
|
|
9
|
-
const value =
|
|
6
|
+
Nas.set("testKey", "testValue");
|
|
7
|
+
const value = Nas.get("testKey");
|
|
10
8
|
assert.equal(value, "testValue");
|
|
11
9
|
});
|
|
12
10
|
|
|
11
|
+
it("should set and get a string object", function () {
|
|
12
|
+
const target = [
|
|
13
|
+
{
|
|
14
|
+
id: 128910,
|
|
15
|
+
supplierCode: "9c6d1ab7ff7a440eba1516b164c06632",
|
|
16
|
+
status: 1,
|
|
17
|
+
city: "",
|
|
18
|
+
},
|
|
19
|
+
];
|
|
20
|
+
Nas.set("testObject", target);
|
|
21
|
+
const value = Nas.get("testObject");
|
|
22
|
+
assert.deepStrictEqual(value, target);
|
|
23
|
+
});
|
|
24
|
+
|
|
13
25
|
it("should handle expiration correctly", function (done) {
|
|
14
|
-
|
|
26
|
+
Nas.set("expiringKey", "expiringValue", 1); // 1秒后过期
|
|
15
27
|
|
|
16
28
|
setTimeout(() => {
|
|
17
|
-
const expiredValue =
|
|
29
|
+
const expiredValue = Nas.get("expiringKey");
|
|
18
30
|
assert.equal(expiredValue, null);
|
|
19
31
|
done();
|
|
20
32
|
}, 1100);
|
|
21
33
|
});
|
|
22
34
|
|
|
23
35
|
it("should return null for expired keys", function () {
|
|
24
|
-
|
|
36
|
+
Nas.set("shortLivedKey", "value", 0.5); // 0.5秒后过期
|
|
25
37
|
setTimeout(() => {
|
|
26
|
-
const value =
|
|
38
|
+
const value = Nas.get("shortLivedKey");
|
|
27
39
|
assert.equal(value, null);
|
|
28
40
|
}, 1000);
|
|
29
41
|
});
|
|
30
42
|
|
|
31
43
|
it("should check if key exists", function () {
|
|
32
|
-
|
|
33
|
-
assert(
|
|
34
|
-
assert(
|
|
44
|
+
Nas.set("existKey", "value");
|
|
45
|
+
assert(Nas.exists("existKey"));
|
|
46
|
+
assert(Nas.exists("nonExistKey") == false);
|
|
35
47
|
});
|
|
36
48
|
|
|
37
49
|
it("should delete a key", function () {
|
|
38
|
-
|
|
39
|
-
assert(
|
|
40
|
-
|
|
41
|
-
assert(
|
|
50
|
+
Nas.set("deleteKey", "value");
|
|
51
|
+
assert(Nas.exists("deleteKey"));
|
|
52
|
+
Nas.del("deleteKey");
|
|
53
|
+
assert(Nas.exists("deleteKey") == false);
|
|
42
54
|
});
|
|
43
55
|
|
|
44
56
|
it("should return default value when key does not exist", function () {
|
|
45
|
-
const defaultValue =
|
|
57
|
+
const defaultValue = Nas.getOrDefault("nonExistingKey", "default");
|
|
46
58
|
assert.equal(defaultValue, "default");
|
|
47
59
|
});
|
|
48
60
|
|
|
49
61
|
it("should return actual value when key exists with getOrDefault", function () {
|
|
50
|
-
|
|
51
|
-
const value =
|
|
62
|
+
Nas.set("existingKey", "actualValue");
|
|
63
|
+
const value = Nas.getOrDefault("existingKey", "defaultValue");
|
|
52
64
|
assert.equal(value, "actualValue");
|
|
53
65
|
});
|
|
54
66
|
|
|
55
67
|
it("should handle expiration with expire method", function (done) {
|
|
56
|
-
|
|
57
|
-
const initialTtl =
|
|
68
|
+
Nas.set("expireTest", "value", 10); // 设置10秒后过期
|
|
69
|
+
const initialTtl = Nas.ttl("expireTest");
|
|
58
70
|
assert(initialTtl > 5); // 初始TTL应该大于5秒
|
|
59
71
|
|
|
60
|
-
|
|
61
|
-
const updatedTtl =
|
|
72
|
+
Nas.expire("expireTest", 1); // 重新设置为1秒后过期
|
|
73
|
+
const updatedTtl = Nas.ttl("expireTest");
|
|
62
74
|
assert(updatedTtl <= 1); // TTL应该小于等于1秒
|
|
63
75
|
|
|
64
76
|
setTimeout(() => {
|
|
65
|
-
const expiredTtl =
|
|
77
|
+
const expiredTtl = Nas.ttl("expireTest");
|
|
66
78
|
assert.equal(expiredTtl, -1); // 已过期,返回-1
|
|
67
79
|
done();
|
|
68
80
|
}, 1100);
|
|
69
81
|
});
|
|
70
82
|
|
|
71
83
|
it("should handle expiration with expireAt method", function (done) {
|
|
72
|
-
|
|
84
|
+
Nas.set("expireAtTest", "value");
|
|
73
85
|
const futureTime = Date.now() + 1000; // 1秒后
|
|
74
|
-
|
|
86
|
+
Nas.expireAt("expireAtTest", futureTime);
|
|
75
87
|
|
|
76
88
|
setTimeout(() => {
|
|
77
|
-
const expiredAtValue =
|
|
89
|
+
const expiredAtValue = Nas.get("expireAtTest");
|
|
78
90
|
assert(expiredAtValue == null); // 已过期,应该返回null
|
|
79
91
|
done();
|
|
80
92
|
}, 1100);
|
|
81
93
|
});
|
|
82
94
|
|
|
83
|
-
it("should flush
|
|
84
|
-
|
|
85
|
-
|
|
95
|
+
it("should flush only expired cache entries", function (done) {
|
|
96
|
+
// 设置一个永不过期的键
|
|
97
|
+
Nas.set("permanentKey", "permanentValue", -1);
|
|
98
|
+
// 设置一个会过期的键
|
|
99
|
+
Nas.set("expiringKey", "expiringValue", 0.5); // 0.5秒后过期
|
|
86
100
|
|
|
87
|
-
|
|
88
|
-
|
|
101
|
+
setTimeout(() => {
|
|
102
|
+
// 此时expiringKey已经过期,但是permanentKey仍然有效
|
|
103
|
+
Nas.flushAll(); // 应该只清除过期的键
|
|
89
104
|
|
|
90
|
-
|
|
105
|
+
// 永不过期的键应该仍然存在
|
|
106
|
+
assert(Nas.get("permanentKey") == "permanentValue");
|
|
107
|
+
// 过期的键应该已经被清除
|
|
108
|
+
assert(Nas.get("expiringKey") == null);
|
|
109
|
+
assert(Nas.exists("expiringKey") == false);
|
|
91
110
|
|
|
92
|
-
|
|
93
|
-
|
|
111
|
+
// 清理测试数据
|
|
112
|
+
Nas.del("permanentKey");
|
|
113
|
+
done();
|
|
114
|
+
}, 1000); // 等待expiringKey过期后再测试
|
|
94
115
|
});
|
|
95
116
|
|
|
96
117
|
it("should handle non-expiring keys (timeout = -1)", function () {
|
|
97
|
-
|
|
98
|
-
const value =
|
|
118
|
+
Nas.set("permanentKey", "permanentValue", -1);
|
|
119
|
+
const value = Nas.get("permanentKey");
|
|
99
120
|
assert.equal(value, "permanentValue");
|
|
100
121
|
});
|
|
101
122
|
});
|