ค้นหาเว็บไซต์

typescript - ตรวจสอบและอัปเดต localStorage หากผู้ใช้เปิดเบราว์เซอร์อีกครั้งหลังจากระบบ/เบราว์เซอร์เกิดข้อผิดพลาดใน Javascript


ฉันกำลังพยายามอัปเดตค่าของรายการที่เก็บอยู่ใน localStorage ตามค่าของ sessionStorage และวัตถุ window ของแต่ละแท็บ ฉันมีสถานการณ์ที่แตกต่างกันดังนี้:

  1. ผู้ใช้เริ่มกระบวนการใหม่ในแต่ละแท็บ
  2. รีเฟรช/ปิดแท็บ
  3. เบราว์เซอร์ถูกปิด
  4. ระบบล่ม - ปุ่มปิดเบราว์เซอร์ไม่ได้ถูกคลิกที่นี่ นี่คือการปิดโดยตรง

ฉันได้เขียนโค้ดดังต่อไปนี้ โค้ดนี้อัปเดตค่าทั้งหมดในที่เก็บข้อมูลสำหรับสองกรณีแรกที่กล่าวถึงข้างต้น แต่ไม่ได้อัปเดตในกรณีที่สามและสี่ ฉันสามารถเปลี่ยนแปลงอะไรเพื่อให้สิ่งนี้ทำงานได้?

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

บทความที่เกี่ยวข้อง