scriptcat
scriptcat copied to clipboard
[v1.3] 異步 getValue/getValues/listValues 相关修改
概述 Descriptions
依存: #949
- #898 取值前确保读取的是最新 values 否则向service_worker发消息,取得最新的 valueUpdated
- #943
- 这个可以单独合并到 main. 只是避免合并问题,一并提交到同一个PR
变更内容 Changes
截图 Screenshots
测试代码(一):
修改后:GM.listValues() 能在冲突中取得最新,而且不会因本地缓存与valueUpdate冲突而造成次序不一
( useAsync 改为 false 的话就能看 GM_xxxx 的结果 )
// ==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);
}
})();
测试代码(二):
(有GM_lock 做时间控制)修改后 GM.getValue 的列表新增没问题
// ==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());
});
})();
怎么都到这个分支去了 develop/raw-message