typescript - ตรวจสอบและอัปเดต localStorage หากผู้ใช้เปิดเบราว์เซอร์อีกครั้งหลังจากระบบ/เบราว์เซอร์เกิดข้อผิดพลาดใน Javascript
ฉันกำลังพยายามอัปเดตค่าของรายการที่เก็บอยู่ใน localStorage ตามค่าของ sessionStorage และวัตถุ window ของแต่ละแท็บ ฉันมีสถานการณ์ที่แตกต่างกันดังนี้:
- ผู้ใช้เริ่มกระบวนการใหม่ในแต่ละแท็บ
- รีเฟรช/ปิดแท็บ
- เบราว์เซอร์ถูกปิด
- ระบบล่ม - ปุ่มปิดเบราว์เซอร์ไม่ได้ถูกคลิกที่นี่ นี่คือการปิดโดยตรง
ฉันได้เขียนโค้ดดังต่อไปนี้ โค้ดนี้อัปเดตค่าทั้งหมดในที่เก็บข้อมูลสำหรับสองกรณีแรกที่กล่าวถึงข้างต้น แต่ไม่ได้อัปเดตในกรณีที่สามและสี่ ฉันสามารถเปลี่ยนแปลงอะไรเพื่อให้สิ่งนี้ทำงานได้?
const data = useRef('');
const setDatatInLocalStorage = (event?) => {
if (!event) {
event = window.event;
}
if (event.key == 'dataList') {
const localStorageDataList = JSON.parse(event.newValue || '[]');
localStorage.setItem('dataList', JSON.stringify(localStorageDataList));
}
};
window.addEventListener('storage', setDatatInLocalStorage, {
once: true,
});
window.onbeforeunload = function () {
const sessionStorageDataList = JSON.parse(
sessionStorage.getItem('dataList') || '[]',
);
if (sessionStorageDataList.length > 0) {
let localStorageDataList = JSON.parse(
localStorage.getItem('dataList') || '[]',
);
if (localStorageDataList.length > 0) {
localStorageDataList = localStorageDataList.filter(
(data) => !sessionStorageDataList.includes(data),
);
localStorage.setItem('dataList', JSON.stringify(localStorageDataList));
}
}
sessionStorage.removeItem('dataList');
};
window.onload = function () {
const sessionStorageDataList = JSON.parse(
sessionStorage.getItem('dataList') || '[]',
);
if (sessionStorageDataList.length > 0) {
let localStorageDataList = JSON.parse(
localStorage.getItem('dataList') || '[]',
);
if (localStorageDataList.length > 0) {
localStorageDataList = localStorageDataList.filter(
(data) => !sessionStorageDataList.includes(data),
);
localStorage.setItem('dataList', JSON.stringify(localStorageDataList));
}
}
sessionStorage.removeItem('dataList');
};
const updatedataList = (data) => {
if ((window as any).dataList) {
(window as any).dataList.push(data);
} else {
(window as any).dataList = [data];
}
sessionStorage.setItem(
'dataList',
JSON.stringify((window as any).dataList),
);
if (
'dataList' in localStorage &&
!isEmpty(localStorage.getItem('dataList'))
) {
const localStorageDataList = JSON.parse(
localStorage.getItem('dataList') || '[]',
);
localStorageDataList.push(data);
localStorage.setItem('dataList', JSON.stringify(localStorageDataList));
} else {
localStorage.setItem('dataList', JSON.stringify([data]));
}
};
const removedataList = () => {
if ((window as any).dataList) {
(window as any).dataList.shift();
}
sessionStorage.setItem(
'dataList',
JSON.stringify((window as any).dataList),
);
if ('dataList' in localStorage) {
let localStorageDataList = JSON.parse(
localStorage.getItem('dataList') || '[]',
);
localStorageDataList = localStorageDataList.filter(
(item) => item !== data.current,
);
localStorage.setItem('dataList', JSON.stringify(localStorageDataList));
}
};
const callData = () => {
if (!data.current) {
data.current = uuid();
}
updatedataList(data.current);
const intervalID = setInterval(() => {
const localStorageDataList = JSON.parse(
localStorage.getItem('dataList') || '[]',
);
if (localStorageDataList.indexOf(data.current) === 0) {
clearInterval(intervalID);
//logic to execute
removedataList()
}
}, 10000);
};
ตรงนี้ฉันต้องการอัปเดต dataList ในทุกที่เก็บข้อมูล มันคืออาเรย์ที่ถูกใช้เป็นคิว ฉันได้ล้าง sessionStorage และ localStorage ทั้งหมดเมื่อปิดเบราว์เซอร์แล้ว (ไม่ว่าจะโดยผู้ใช้คลิกหรือเกิดระบบล่ม) ฉันสามารถทำแบบนี้ได้อย่างไร? ข้อเสนอแนะในการดำเนินการอื่นก็ยินดีเช่นกัน หากวิธีของฉันไม่ทำงานในทุกกรณีการใช้งาน
คำตอบ #1
ในการค้นหาออนไลน์ ฉันเจอแนวคิดเกี่ยวกับการนำความต่างของเวลาระหว่างเวลาล่าสุดและเวลาที่ปรับปรุงล่าสุดมาใช้ ตามนั้น ด้านล่างเป็นตัวอย่างโค้ด:
let intervalId: { current: NodeJS.Timeout | null } =
useRef(null);
// Start a setInterval that updates the timestamp every second
const updateTimeStampForCurrentIdInLocalStorage = (id) => {
intervalId.current = setInterval(() => {
const timestampsObj = getTimerObjectFromLocalStorage();
const currentTime = new Date();
timestampsObj[id] = currentTime.getTime();
localStorage.setItem(
'timestampsObj',
JSON.stringify(timestampsObj),
);
}, 1000);
};
const mainFunction = () => {
const mainProcessIntervalId = setInterval(() => {
// timestampobj from localstorage.
const timestampsObj = JSON.parse(
localStorageRef.current.getItem('timestampsObj') || '{}',
);
if (someCondition) {
clearInterval(mainProcessIntervalId);
//continue
} else {
const idsInTimer = Object.keys(timestampsObj).filter(
(id) => id !== currentId,
);
idsInTimer.forEach((id) => {
const currentTime = new Date();
const lastUpdated = new Date(timestampsObj[id]);
const timeDiff =
(currentTime.getTime() - lastUpdated.getTime()) / 1000;
if (timeDiff > thresholdTime) {
const timestampsObj = getUuidTimerObjectFromLocalStorage();
if ((timestampsObj.length > 0)) {
delete timestampsObj[id];
localStorage.setItem('timestampsObj', JSON.stringify(timestampsObj));
}
if (intervalId.current) {
clearInterval(intervalId.current || 0);
}
}
});
}
}, 1000);
}
เพื่อเอาข้อมูลออกเมื่อรีเฟรช ควรเรียกใช้ฟังก์ชันในเหตุการณ์ onBeforeUnload หลักการหลักคือการตรวจสอบ timeDiff ระหว่างเวลาปัจจุบันกับเวลาที่มีการอัปเดตล่าสุดของ ID ที่มีอยู่ และถ้ามันมากกว่าค่าที่กำหนดไว้ก็ให้ลบออก
คำตอบ #2
เกี่ยวกับปัญหาของคุณ
คำอธิบาย
เรา เบราว์เซอร์หรือระบบปฏิบัติการ ไม่มีใครรู้ว่าเมื่อใดอุปกรณ์จะปิดตัวลงอย่างกะทันหัน ดังนั้นการรอเหตุการณ์นั้นจึงเป็นไปไม่ได้
วิธีแก้ปัญหา
ดังนั้นให้บันทึกลงฮาร์ดดิสก์เท่านั้นไม่ว่าสิ่งที่อยู่ในข้อมูลนี้ ในโค้ดนี้ฉันได้สำรองข้อมูล dataList จาก session ไปยัง local โดยใช้ชื่อเล่น _dataList และกู้คืนเมื่อโหลดหน้าซ้ำ (ฉันสามารถลบ session ได้ แต่คิดว่าคุณต้องการมันเพื่อสื่อสารกับเซิร์ฟเวอร์)
const data = useRef('');
const setDatatInLocalStorage = (event?) => {
if (!event) {
event = window.event;
}
if (event.key == 'dataList') {
const localStorageDataList = JSON.parse(event.newValue || '[]');
localStorage.setItem('dataList', JSON.stringify(localStorageDataList));
}
};
window.addEventListener('storage', setDatatInLocalStorage, {
once: true,
});
function syncSeasonToLocal() {
const sessionStorageDataList = JSON.parse(
sessionStorage.getItem('dataList') || '[]',
);
if (sessionStorageDataList.length > 0) {
let localStorageDataList = JSON.parse(
localStorage.getItem('dataList') || '[]',
);
if (localStorageDataList.length > 0) {
localStorageDataList = localStorageDataList.filter(
(data) => !sessionStorageDataList.includes(data),
);
localStorage.setItem('dataList', JSON.stringify(localStorageDataList));
}
}
sessionStorage.removeItem('dataList');
};
onload = () => {
sessionStorage.setItem("dataList", localStorage.getItem("_dataList"))
syncSeasonToLocal()
}
onbeforeunload
= syncSeasonToLocal
const updatedataList = (data) => {
if ((window as any).dataList) {
(window as any).dataList.push(data);
} else {
(window as any).dataList = [data];
}
sessionStorage.setItem(
'dataList',
JSON.stringify((window as any).dataList),
);
localStorage.setItem("_dataList", JSON.stringify((window as any).dataList))
if (
'dataList' in localStorage &&
!isEmpty(localStorage.getItem('dataList'))
) {
const localStorageDataList = JSON.parse(
localStorage.getItem('dataList') || '[]',
);
localStorageDataList.push(data);
localStorage.setItem('dataList', JSON.stringify(localStorageDataList));
} else {
localStorage.setItem('dataList', JSON.stringify([data]));
}
};
const removedataList = () => {
if ((window as any).dataList) {
(window as any).dataList.shift();
}
sessionStorage.setItem(
'dataList',
JSON.stringify((window as any).dataList),
);
localStorage.setItem("_dataList", JSON.stringify((window as any).dataList))
if ('dataList' in localStorage) {
let localStorageDataList = JSON.parse(
localStorage.getItem('dataList') || '[]',
);
localStorageDataList = localStorageDataList.filter(
(item) => item !== data.current,
);
localStorage.setItem('dataList', JSON.stringify(localStorageDataList));
}
};
const callData = () => {
if (!data.current) {
data.current = uuid();
}
updatedataList(data.current);
const intervalID = setInterval(() => {
const localStorageDataList = JSON.parse(
localStorage.getItem('dataList') || '[]',
);
if (localStorageDataList.indexOf(data.current) === 0) {
clearInterval(intervalID);
//logic to execute
removedataList()
}
}, 10000);
};
เกี่ยวกับรหัสของคุณ
ใช่ เมื่อฉันแก้มัน ฉันรู้สึกเหมือนกำลังทรยศตัวเอง มันไม่มีประเภทและการประกาศ มันยังใช้ property ของ global ใน window และคุณบังคับค่าของมัน มันเป็นการดูหมิ่นคนที่ออกแบบ typescript
