异歩 GM.getValue/getValues/listValues 修正#898
Closed
cyfung1031 wants to merge 9 commits intoscriptscat:release/v1.3from
Closed
异歩 GM.getValue/getValues/listValues 修正#898cyfung1031 wants to merge 9 commits intoscriptscat:release/v1.3from
cyfung1031 wants to merge 9 commits intoscriptscat:release/v1.3from
Conversation
Collaborator
Author
a123e26 to
04d6641
Compare
Contributor
There was a problem hiding this comment.
Pull Request Overview
此 PR 为 GM.getValue、GM.listValues 和 GM.getValues 等异步 API 添加了数据同步机制,确保这些 API 在读取值之前能获取到最新的数据库状态。
主要变更:
- 在 ValueService 中添加
updatetime字段跟踪,记录每次值更新的时间戳 - 实现
GM_waitForFreshValueStateAPI,用于获取最新的 updatetime - 修改 GM.getValue、GM.listValues、GM.getValues 等异步 API,在读取前等待数据同步到最新状态
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/app/service/service_worker/value.ts | 在 setValue 和 setValues 方法中添加 updatetime 跟踪逻辑,新增 waitForFreshValueState 方法 |
| src/app/service/service_worker/gm_api.ts | 添加 GM_waitForFreshValueState API 处理函数 |
| src/app/service/content/types.ts | 在 ValueUpdateDataEncoded 类型中添加 updatetime 字段 |
| src/app/service/content/gm_api.ts | 实现 waitForFreshValueState 函数,修改 GM.getValue、GM.listValues、GM.getValues 使用该函数;修正一处注释的繁体字 |
| src/app/service/content/gm_api.test.ts | 添加 valueDaoUpdatetimeFix 辅助函数,更新测试以支持新的同步机制;修正正则表达式匹配模式 |
Comment on lines
337
to
347
| async GM_waitForFreshValueState(request: GMApiRequest<[boolean]>, sender: IGetSender) { | ||
| const param = request.params; | ||
| if (param.length !== 1) { | ||
| throw new Error("there must be one parameter"); | ||
| } | ||
| const ret = await this.value.waitForFreshValueState(request.script.uuid, { | ||
| runFlag: request.runFlag, | ||
| tabId: sender.getSender()?.tab?.id || -1, | ||
| }); | ||
| return ret; | ||
| } |
There was a problem hiding this comment.
GM_waitForFreshValueState 函数接收的参数声明为 GMApiRequest<[boolean]>,并验证参数长度必须为 1,但实际上并未使用该参数。在 content/gm_api.ts:255 调用时传递的是 [true],但在函数内部完全没有使用 request.params[0]。要么应该使用该参数,要么应该将类型改为 GMApiRequest<[]> 并移除长度验证。
Collaborator
Author
There was a problem hiding this comment.
之前好像不放东西的话,传送有问题。我没有看到其他没用param的API。
所以就放一个 true 了
先这样吧
Collaborator
Author
|
研究一下效能提升。先轉 draft |
35d670e to
79ad4e2
Compare
7eb600c to
035ce3d
Compare
Collaborator
Author
|
@CodFrm 改好了 测试代码(一):修改后: // ==UserScript==
// @name 测试 GM.getValue 能否取得最新值
// @namespace yourname.scripts
// @version 0.1.0
// @description 把当前网页URL保存到存储列表中
// @author You
// @match *://*/*
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @grant GM_listValues
// @grant GM.getValue
// @grant GM.setValue
// @grant GM.deleteValue
// @grant GM.listValues
// @grant GM_addValueChangeListener
// @grant GM_removeValueChangeListener
// ==/UserScript==
(function () {
'use strict';
let useAsync = true;
const rid = `${(Math.floor(Math.random() * 5000) + 4000).toString(36)}`;
const trigger = async () => {
console.log(`[${rid}]`,"trigger in " + location.href, "current time = " + Date.now());
useAsync ? action2() : action1();
}
let k = 0;
const action1 = async () => {
++k;
GM_setValue(`${"list_"}${rid}${k}`, Date.now());
console.log(`[${rid}]`, GM_listValues());
};
const action2 = async () => {
++k;
await GM.setValue(`${"list_"}${rid}${k}`, Date.now());
console.log(`[${rid}]`, await GM.listValues());
};
const wins = [];
let tc0;
window.addEventListener("message", (e) => {
if (e.data && typeof e.data === "object" && e.data?.test_call_id && e.data?.type === "response_tc") {
const tc1 = e.data.test_call_id;
if (tc1 === tc0) {
trigger();
}
}
});
if (location.search.startsWith("?test_call=") && top !== window) {
const usp = new URLSearchParams(location.search);
const tc = usp.get("test_call");
if (tc) {
tc0 = tc;
window.top.postMessage({ type: "done_iframe_tc", test_call_id: tc }, "*");
}
} else if (window.location.href.includes("example.com") && top === window) {
const test_call_id = `tc${Date.now()}_${Math.random()}`;
tc0 = test_call_id;
let q = 1;
let ec = 0;
const doFunc = async (elements) => {
console.log(`[${rid}]`,"---- ADD SOME INFO... ------");
await (useAsync ? action2() : action1());
await (useAsync ? action2() : action1());
await (useAsync ? action2() : action1());
console.log(`[${rid}]`,"---------------------------");
setTimeout(() => {
console.log(`[${rid}]`,"do trigger");
for (const iframe of elements) {
try {
iframe.contentWindow.postMessage({ type: "response_tc", test_call_id },
"*"
)
} catch (e) {
// ignored
}
}
window.postMessage({ type: "response_tc", test_call_id }, "*");
setTimeout(async () => {
console.log(`[${rid}]`,"final list", await GM.listValues());
}, 1500)
}, 1500);
}
window.addEventListener("message", (e) => {
if (e.data && typeof e.data === "object" && e.data?.test_call_id && e.data?.type === "done_iframe_tc") {
const tc = e.data.test_call_id;
if (tc === test_call_id) {
const elements = document.querySelectorAll("iframe.tt0011");
// wins.push([e.source, e.origin]);
wins.push(1);
if (wins.length === elements.length && elements.length === ec && q) {
q = 0;
doFunc(elements);
}
}
}
});
const makeIframe = () => {
const elm = document.body.appendChild(document.createElement("iframe"));
elm.classList.add("tt0011");
return elm;
}
ec = 3;
setTimeout(()=>{
makeIframe().src = `https://example.com/?test_call=${test_call_id}`;
}, 1800);
setTimeout(()=>{
makeIframe().src = `https://example.com/?test_call=${test_call_id}`;
}, 2400);
setTimeout(() => {
makeIframe().src = `https://example.com/?test_call=${test_call_id}`;
}, 3200);
}
})();测试代码(二):(有 // ==UserScript==
// @name Example Script for GM_lock
// @namespace yourname.scripts
// @version 0.1
// @description 把当前网页URL保存到存储列表中
// @author You
// @match *://*/*
// @grant GM.getValue
// @grant GM.setValue
// @grant GM.setValues
// @grant GM.deleteValue
// @grant GM.deleteValues
// @grant GM.listValues
// @grant GM_addValueChangeListener
// @grant GM_removeValueChangeListener
// @require https://update.greasyfork.org/scripts/554436/1692608/GM_lock.js
// @noframes
// ==/UserScript==
/* global GM_lock */
(function () {
'use strict';
GM_lock("lock_urls", async () => {
console.log("开始", Date.now(), performance.now());
// 等一下这个页面SC的缓存更新
// await new Promise(resolve => setTimeout(resolve, 50));
// 从存储中读取已有的列表
let list = await GM.getValue('list', []); // 设置默认值为空数组
// 如果当前URL不在列表中,就添加进去
console.log("初始列表:", list.slice());
if (!list.includes(location.href)) {
list.push(location.href);
await GM.setValue('list', list);
console.log('✅ 已保存此页面到列表:', location.href);
} else {
console.log('ℹ️ 当前页面已在列表中');
}
// 可选:在控制台查看当前列表
console.log('当前列表:', list.slice());
// 等一下其他页面SC的缓存更新
// await new Promise(resolve => setTimeout(resolve, 50));
console.log("结束", Date.now(), performance.now());
});
})(); |
Collaborator
Author
|
和 #936 有关连的改动。 我先开一个 分支 develop/raw-message 处理一下。 |
This was referenced Nov 13, 2025
Collaborator
Author
|
移至 #950 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

概述 Descriptions
异歩 GM.getValue/getValues/listValues 修正
变更内容 Changes
增加内部函数
GM_waitForFreshValueState, 会传最新的scriptRes.updatetime若valueUpdate未触发,把Promise加至
readFreshes进行等待截图 Screenshots