workbox-background-sync

เมื่อส่งข้อมูลไปยังเว็บเซิร์ฟเวอร์ คำขออาจล้มเหลวในบางครั้ง ทั้งนี้ อาจเป็นเพราะผู้ใช้ขาดการเชื่อมต่อ หรืออาจเป็นเพราะ เซิร์ฟเวอร์ขัดข้อง ไม่ว่าในกรณีใดก็ตาม คุณควรลองส่งคำขอ อีกครั้งในภายหลัง

BackgroundSync API ใหม่ คือวิธีการแก้ปัญหานี้ที่ดี เมื่อโปรแกรมทำงานของบริการตรวจพบว่า คำขอเครือข่ายล้มเหลว เครือข่ายสามารถลงทะเบียนเพื่อรับเหตุการณ์ sync ซึ่งจะส่งเมื่อเบราว์เซอร์คิดว่าการเชื่อมต่อกลับมาแล้ว โปรดทราบว่าระบบจะส่งเหตุการณ์การซิงค์ได้ แม้ว่าผู้ใช้จะออกจาก แอปพลิเคชัน จึงมีประสิทธิภาพมากกว่าวิธีการดั้งเดิม กำลังลองส่งคำขอที่ล้มเหลวอีกครั้ง

การซิงค์พื้นหลังของ Workbox ได้รับการออกแบบมาเพื่อใช้ BackgroundSync API และผสานรวมการใช้งานกับโมดูล Workbox อื่นๆ ทั้งนี้ ใช้กลยุทธ์ทางเลือกสำรองสำหรับเบราว์เซอร์ที่ยังไม่ได้ใช้ BackgroundSync

เบราว์เซอร์ที่รองรับ BackgroundSync API จะเล่นซ้ำโดยอัตโนมัติไม่สำเร็จ ในนามของคุณที่ ที่มีการจัดการโดยเบราว์เซอร์ ซึ่งมีแนวโน้มที่จะใช้ Exponential Backoff ระหว่างการเล่นซ้ำ ในเบราว์เซอร์ที่ ไม่รองรับ BackgroundSync API ตั้งแต่ต้น การซิงค์พื้นหลังของ Workbox จะ พยายามเล่นซ้ำโดยอัตโนมัติทุกครั้งที่โปรแกรมทำงานของบริการเริ่มต้นทำงาน

การใช้งานพื้นฐาน

วิธีที่ง่ายที่สุดในการใช้การซิงค์ในเบื้องหลังคือการใช้ Plugin ที่จะ จัดคิวคำขอที่ล้มเหลวโดยอัตโนมัติ แล้วลองอีกครั้งเมื่อในอนาคต sync ของเหตุการณ์

import {BackgroundSyncPlugin} from 'workbox-background-sync';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

const bgSyncPlugin = new BackgroundSyncPlugin('myQueueName', {
  maxRetentionTime: 24 * 60, // Retry for max of 24 Hours (specified in minutes)
});

registerRoute(
  /\/api\/.*\/*.json/,
  new NetworkOnly({
    plugins: [bgSyncPlugin],
  }),
  'POST'
);

BackgroundSyncPlugin เจาะเข้ามาใน fetchDidFail Callback ของปลั๊กอิน และ ระบบจะเรียกใช้ fetchDidFail ในกรณีที่มีการยกเว้นเท่านั้น ซึ่งน่าจะถึงกำหนด จนเครือข่ายล้มเหลว ซึ่งหมายความว่าระบบจะไม่ส่งคำขอซ้ำหากมี คำตอบที่ได้รับ สถานะข้อผิดพลาด 4xx หรือ 5xx หากต้องการลองส่งคำขอทั้งหมดที่ทำให้เกิดคำขออีกครั้ง เช่น สถานะ 5xx คุณสามารถทำได้โดย การเพิ่มปลั๊กอิน fetchDidSucceed กลยุทธ์ของคุณ ได้แก่

const statusPlugin = {
  fetchDidSucceed: ({response}) => {
    if (response.status >= 500) {
      // Throwing anything here will trigger fetchDidFail.
      throw new Error('Server error.');
    }
    // If it's not 5xx, use the response as-is.
    return response;
  },
};

// Add statusPlugin to the plugins array in your strategy.

การใช้งานขั้นสูง

การซิงค์พื้นหลังของ Workbox ยังมีคลาส Queue ที่คุณสามารถ สร้างอินสแตนซ์และเพิ่มคำขอที่ล้มเหลวไปยัง จัดเก็บคำขอที่ล้มเหลวไว้ ใน IndexedDB และจะลองใหม่เมื่อเบราว์เซอร์คิดว่าการเชื่อมต่อกลับมาแล้ว (เช่น เมื่อได้รับเหตุการณ์การซิงค์)

การสร้างคิว

หากต้องการสร้างคิวการซิงค์พื้นหลังของ Workbox คุณต้องสร้างคิวด้วย ชื่อคิว (ซึ่งต้องไม่ซ้ำกันสำหรับ origin):

import {Queue} from 'workbox-background-sync';

const queue = new Queue('myQueueName');

ชื่อคิวจะใช้เป็นส่วนหนึ่งของชื่อแท็กที่ได้รับ แก้ไข register() จากทั่วโลก SyncManager ตอนนี้ ยังใช้เป็น ชื่อ Object Store สำหรับ ฐานข้อมูล IndexedDB

การเพิ่มคำขอลงในคิว

เมื่อสร้างอินสแตนซ์ในคิวแล้ว คุณสามารถเพิ่มคำขอที่ล้มเหลวลงในอินสแตนซ์นั้นได้ คุณเพิ่มคำขอที่ล้มเหลวโดยการเรียกใช้เมธอด .pushRequest() ตัวอย่างเช่น โค้ดต่อไปนี้จะตรวจจับคำขอที่ล้มเหลวและเพิ่มลงในคิว

import {Queue} from 'workbox-background-sync';

const queue = new Queue('myQueueName');

self.addEventListener('fetch', event => {
  // Add in your own criteria here to return early if this
  // isn't a request that should use background sync.
  if (event.request.method !== 'POST') {
    return;
  }

  const bgSyncLogic = async () => {
    try {
      const response = await fetch(event.request.clone());
      return response;
    } catch (error) {
      await queue.pushRequest({request: event.request});
      return error;
    }
  };

  event.respondWith(bgSyncLogic());
});

เมื่อเพิ่มลงในคิวแล้ว ระบบจะส่งคำขอซ้ำโดยอัตโนมัติเมื่อ Service Worker ได้รับเหตุการณ์ sync (ซึ่งเกิดขึ้นเมื่อเบราว์เซอร์ คิดว่าการเชื่อมต่อกลับคืนมา) เบราว์เซอร์ที่ไม่รองรับแท็ก BackgroundSync API จะลองเข้าคิวใหม่ทุกครั้งที่โปรแกรมทำงานของบริการ ขึ้นมา ซึ่งกำหนดให้หน้าเว็บที่ควบคุมโปรแกรมทำงานของบริการต้อง จึงจะทำงานได้ไม่ดีนัก

การทดสอบการซิงค์พื้นหลังของกล่องงาน

การทดสอบ BackgroundSync ค่อนข้างง่ายและยาก ด้วยเหตุผลหลายประการ

วิธีที่ดีที่สุดในการทดสอบการติดตั้งใช้งานคือดำเนินการดังต่อไปนี้

  1. โหลดหน้าเว็บและลงทะเบียน Service Worker ของคุณ
  2. ปิดเครือข่ายของคอมพิวเตอร์หรือปิดเว็บเซิร์ฟเวอร์
    • อย่าใช้นักพัฒนาซอฟต์แวร์ Chrome แบบออฟไลน์ ช่องทำเครื่องหมายออฟไลน์ใน เครื่องมือสำหรับนักพัฒนาเว็บจะมีผลเฉพาะกับคำขอจากหน้าเว็บเท่านั้น คำขอ Service Worker จะยังดำเนินต่อไป
  3. สร้างคำขอเครือข่ายที่ควรอยู่ในคิวกับการซิงค์พื้นหลังของ Workbox
    • คุณสามารถตรวจสอบคำขอที่อยู่ในคิวได้โดยดูที่ Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests
  4. จากนั้นให้เปิดเครือข่ายหรือเว็บเซิร์ฟเวอร์
  5. บังคับใช้เหตุการณ์ sync แรกเริ่มโดยไปที่ Chrome DevTools > Application > Service Workers ป้อนชื่อแท็กของ workbox-background-sync:<your queue name> ตำแหน่งที่ <your queue name> ควรอยู่ ชื่อคิวที่คุณตั้งค่าไว้ จากนั้นคลิก "ซิงค์"

    ตัวอย่างปุ่มซิงค์ในเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome

  6. คุณควรเห็นว่าคำขอเครือข่ายได้รับการดำเนินการสำหรับคำขอที่ล้มเหลวและ ตอนนี้ข้อมูล IndexedDB ควรว่างเปล่าแล้วเนื่องจากคำขอ เล่นซ้ำสำเร็จ

ประเภท

BackgroundSyncPlugin

คลาสที่ใช้ Callback วงจรชีวิต fetchDidFail จึงทำให้ เพิ่มคำขอที่ล้มเหลวไปยังคิวการซิงค์ในเบื้องหลังได้ง่ายขึ้น

พร็อพเพอร์ตี้

  • เครื่องมือสร้าง

    เป็นโมฆะ

    ฟังก์ชัน constructor มีลักษณะดังนี้

    (name: string, options?: QueueOptions) => {...}

    • ชื่อ

      สตริง

      โปรดดูworkbox-background-sync.Queue สำหรับรายละเอียดพารามิเตอร์

    • ตัวเลือก

      QueueOptions ไม่บังคับ

Queue

คลาสสำหรับจัดการการจัดเก็บคำขอที่ล้มเหลวใน IndexedDB แล้วลองใหม่ ในภายหลัง ทุกส่วนของกระบวนการจัดเก็บและการเล่นซ้ำสามารถสังเกตได้ผ่านทาง Callback

พร็อพเพอร์ตี้

  • เครื่องมือสร้าง

    เป็นโมฆะ

    สร้างอินสแตนซ์ของคิวที่มีตัวเลือกที่ระบุ

    ฟังก์ชัน constructor มีลักษณะดังนี้

    (name: string, options?: QueueOptions) => {...}

    • ชื่อ

      สตริง

      ชื่อที่ไม่ซ้ำกันสำหรับคิวนี้ ชื่อนี้ต้องเป็น ไม่ซ้ำกัน เนื่องจากใช้ในการบันทึกเหตุการณ์การซิงค์และคำขอจัดเก็บ ใน IndexedDB ที่เจาะจงสำหรับอินสแตนซ์นี้ ระบบจะแสดงข้อผิดพลาดหาก ตรวจพบชื่อที่ซ้ำกัน

    • ตัวเลือก

      QueueOptions ไม่บังคับ

  • ชื่อ

    สตริง

  • getAll

    เป็นโมฆะ

    แสดงรายการทั้งหมดที่ยังไม่หมดอายุ (ต่อ maxRetentionTime) ระบบจะนำรายการที่หมดอายุออกจากคิว

    ฟังก์ชัน getAll มีลักษณะดังนี้

    () => {...}

    • returns

      Promise&lt;QueueEntry[]&gt;

  • popRequest

    เป็นโมฆะ

    ลบและส่งกลับคำขอสุดท้ายในคิว (พร้อมด้วย และข้อมูลเมตาทั้งหมด) ออบเจ็กต์ที่แสดงผลจะอยู่ในรูปแบบ {request, timestamp, metadata}

    ฟังก์ชัน popRequest มีลักษณะดังนี้

    () => {...}

    • returns

      Promise&lt;QueueEntry&gt;

  • pushRequest

    เป็นโมฆะ

    จัดเก็บคำขอที่ส่งผ่านใน IndexedDB (พร้อมการประทับเวลาและ ) ในช่วงท้ายของคิวได้ด้วย

    ฟังก์ชัน pushRequest มีลักษณะดังนี้

    (entry: QueueEntry) => {...}

    • รายการ

      QueueEntry

    • returns

      คำสัญญา<โมฆะ>

  • registerSync

    เป็นโมฆะ

    ลงทะเบียนเหตุการณ์การซิงค์ที่มีแท็กเฉพาะสำหรับอินสแตนซ์นี้

    ฟังก์ชัน registerSync มีลักษณะดังนี้

    () => {...}

    • returns

      คำสัญญา<โมฆะ>

  • replayRequests

    เป็นโมฆะ

    วนซ้ำคำขอแต่ละรายการในคิวและพยายามดึงข้อมูลอีกครั้ง หากไม่สามารถดึงข้อมูลคำขอใดๆ ได้ ระบบจะนำคำขอนั้นกลับไปยังตำแหน่งเดิมใน คิว (ซึ่งจะบันทึกการลองใหม่สำหรับเหตุการณ์การซิงค์ครั้งถัดไป)

    ฟังก์ชัน replayRequests มีลักษณะดังนี้

    () => {...}

    • returns

      คำสัญญา<โมฆะ>

  • shiftRequest

    เป็นโมฆะ

    นำออกและส่งกลับคำขอแรกในคิว (พร้อมด้วย และข้อมูลเมตาทั้งหมด) ออบเจ็กต์ที่แสดงผลจะอยู่ในรูปแบบ {request, timestamp, metadata}

    ฟังก์ชัน shiftRequest มีลักษณะดังนี้

    () => {...}

    • returns

      Promise&lt;QueueEntry&gt;

  • ขนาด

    เป็นโมฆะ

    แสดงผลจำนวนรายการที่อยู่ในคิว โปรดทราบว่ารายการที่หมดอายุ (ต่อ maxRetentionTime) จะรวมอยู่ในจำนวนนี้ด้วยเช่นกัน

    ฟังก์ชัน size มีลักษณะดังนี้

    () => {...}

    • returns

      Promise&lt;number&gt;

  • unshiftRequest

    เป็นโมฆะ

    จัดเก็บคำขอที่ส่งผ่านใน IndexedDB (พร้อมการประทับเวลาและ ข้อมูลเมตา) ที่จุดเริ่มต้นของคิว

    ฟังก์ชัน unshiftRequest มีลักษณะดังนี้

    (entry: QueueEntry) => {...}

    • รายการ

      QueueEntry

    • returns

      คำสัญญา<โมฆะ>

QueueOptions

พร็อพเพอร์ตี้

  • forceSyncFallback

    บูลีน ไม่บังคับ

  • maxRetentionTime

    หมายเลข ไม่บังคับ

  • การซิงค์

    OnSyncCallback ไม่บังคับ

QueueStore

คลาสสำหรับจัดการการจัดเก็บคำขอจากคิวใน IndexedDB จัดทำดัชนีตามชื่อคิวเพื่อให้เข้าถึงได้ง่ายขึ้น

นักพัฒนาแอปส่วนใหญ่ไม่จำเป็นต้องเข้าถึงชั้นเรียนนี้โดยตรง สำหรับ Use Case ขั้นสูง

พร็อพเพอร์ตี้

  • เครื่องมือสร้าง

    เป็นโมฆะ

    เชื่อมโยงอินสแตนซ์นี้กับอินสแตนซ์คิว เพื่อให้รายการที่เพิ่มสามารถ ที่ระบุตามชื่อคิว

    ฟังก์ชัน constructor มีลักษณะดังนี้

    (queueName: string) => {...}

    • queueName

      สตริง

  • deleteEntry

    เป็นโมฆะ

    ลบรายการสำหรับรหัสที่กำหนด

    คำเตือน: วิธีนี้ไม่รับรองว่ารายการที่ถูกลบเป็นของ คิว (นั่นคือ ตรงกับ queueName) แต่ข้อจำกัดนี้ยอมรับได้ เนื่องจากชั้นเรียนนี้จะไม่ปรากฏต่อสาธารณะ การตรวจสอบเพิ่มเติมจะทำให้ วิธีนี้ช้ากว่าที่จำเป็น

    ฟังก์ชัน deleteEntry มีลักษณะดังนี้

    (id: number) => {...}

    • id

      ตัวเลข

    • returns

      คำสัญญา<โมฆะ>

  • getAll

    เป็นโมฆะ

    แสดงรายการทั้งหมดใน Store ที่ตรงกับ queueName

    ฟังก์ชัน getAll มีลักษณะดังนี้

    () => {...}

    • returns

      Promise&lt;QueueStoreEntry[]&gt;

  • popEntry

    เป็นโมฆะ

    นำออกและแสดงผลรายการสุดท้ายในคิวที่ตรงกับ queueName

    ฟังก์ชัน popEntry มีลักษณะดังนี้

    () => {...}

    • returns

      Promise&lt;QueueStoreEntry&gt;

  • pushEntry

    เป็นโมฆะ

    เพิ่มรายการเป็นลำดับสุดท้ายในคิว

    ฟังก์ชัน pushEntry มีลักษณะดังนี้

    (entry: UnidentifiedQueueStoreEntry) => {...}

    • รายการ

      UnidentifiedQueueStoreEntry

    • returns

      คำสัญญา<โมฆะ>

  • shiftEntry

    เป็นโมฆะ

    นำออกและแสดงผลรายการแรกในคิวที่ตรงกับ queueName

    ฟังก์ชัน shiftEntry มีลักษณะดังนี้

    () => {...}

    • returns

      Promise&lt;QueueStoreEntry&gt;

  • ขนาด

    เป็นโมฆะ

    แสดงผลจำนวนรายการใน Store ที่ตรงกับ queueName

    ฟังก์ชัน size มีลักษณะดังนี้

    () => {...}

    • returns

      Promise&lt;number&gt;

  • unshiftEntry

    เป็นโมฆะ

    แทรกรายการในคิวก่อน

    ฟังก์ชัน unshiftEntry มีลักษณะดังนี้

    (entry: UnidentifiedQueueStoreEntry) => {...}

    • รายการ

      UnidentifiedQueueStoreEntry

    • returns

      คำสัญญา<โมฆะ>

StorableRequest

คลาสที่ช่วยให้ง่ายต่อการเรียงลำดับและแยกอนุกรมคำขอเพื่อให้ สามารถจัดเก็บใน IndexedDB ได้

นักพัฒนาแอปส่วนใหญ่ไม่จำเป็นต้องเข้าถึงชั้นเรียนนี้โดยตรง สำหรับ Use Case ขั้นสูง

พร็อพเพอร์ตี้

  • เครื่องมือสร้าง

    เป็นโมฆะ

    ยอมรับข้อมูลออบเจ็กต์คำขอที่ใช้สร้าง Request แต่ยังจัดเก็บไว้ใน IndexedDB ได้ด้วย

    ฟังก์ชัน constructor มีลักษณะดังนี้

    (requestData: RequestData) => {...}

    • requestData

      RequestData

      ออบเจ็กต์ข้อมูลคำขอที่มีฟิลด์ url รวมถึงพร็อพเพอร์ตี้ที่เกี่ยวข้องของ [requestInit]https://fetch.spec.whatwg.org/#requestinit

  • โคลน

    เป็นโมฆะ

    สร้างและแสดงผลโคลนแบบลึกของอินสแตนซ์

    ฟังก์ชัน clone มีลักษณะดังนี้

    () => {...}

  • toObject

    เป็นโมฆะ

    แสดงผลโคลนเชิงลึกของออบเจ็กต์ _requestData ของอินสแตนซ์

    ฟังก์ชัน toObject มีลักษณะดังนี้

    () => {...}

    • returns

      RequestData

  • toRequest

    เป็นโมฆะ

    แปลงอินสแตนซ์นี้เป็นคำขอ

    ฟังก์ชัน toRequest มีลักษณะดังนี้

    () => {...}

    • returns

      ส่งคำขอ

  • fromRequest

    เป็นโมฆะ

    แปลงออบเจ็กต์คำขอเป็นออบเจ็กต์ธรรมดาที่มีโครงสร้างได้ มีการโคลนหรือ JSON-stringified

    ฟังก์ชัน fromRequest มีลักษณะดังนี้

    (request: Request) => {...}

    • ส่งคำขอ

      ส่งคำขอ