Progressive Web App: การทำงานกับ Worker

1. ยินดีต้อนรับ

ในแล็บนี้ คุณจะได้ใช้เว็บแอปพลิเคชันที่มีอยู่แล้วและเพิ่ม Web Worker เพื่อแชร์สถานะระหว่างหน้าต่างที่เปิดอยู่ 2 หน้าต่าง นี่คือ Codelab ประกอบชุดที่ 8 สำหรับเวิร์กชอป Progressive Web App Codelab ก่อนหน้านี้คือ Service Worker Includes นี่คือโค้ดแล็บสุดท้ายในชุด

สิ่งที่คุณจะได้เรียนรู้

  • เพิ่ม Worker ที่แชร์ระหว่างหน้าต่างที่เปิดอยู่หลายหน้าต่าง
  • ใช้ Comlink เพื่อให้การทำงานร่วมกับ Worker ง่ายขึ้น

สิ่งที่ควรทราบ

  • JavaScript

สิ่งที่คุณจะต้องมี

2. เตรียมตัว

เริ่มต้นด้วยการโคลนหรือดาวน์โหลดโค้ดเริ่มต้นที่จำเป็นต่อการทำ Codelab นี้ให้เสร็จสมบูรณ์

หากโคลนที่เก็บ โปรดตรวจสอบว่าคุณอยู่ในสาขา pwa06--working-with-workers ไฟล์ ZIP มีโค้ดสำหรับสาขานั้นด้วย

โค้ดเบสนี้ต้องใช้ Node.js 14 ขึ้นไป เมื่อมีโค้ดแล้ว ให้เรียกใช้ npm ci จากบรรทัดคำสั่งในโฟลเดอร์ของโค้ดเพื่อติดตั้งการอ้างอิงทั้งหมดที่คุณต้องใช้ จากนั้นเรียกใช้ npm start เพื่อเริ่มเซิร์ฟเวอร์สำหรับพัฒนาสำหรับโค้ดแล็บ

ไฟล์ README.md ของซอร์สโค้ดจะอธิบายไฟล์ที่เผยแพร่ทั้งหมด นอกจากนี้ ไฟล์สำคัญที่มีอยู่ซึ่งคุณจะต้องใช้ตลอดทั้งโค้ดแล็บนี้มีดังนี้

ไฟล์สำคัญ

  • js/preview.js - ไฟล์ JavaScript ของหน้าตัวอย่าง
  • js/main.js - ไฟล์ JavaScript ของแอปพลิเคชันหลัก

3. เขียน Worker

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

หากต้องการเริ่มต้น ให้สร้างไฟล์ js/worker.js ด้วยโค้ดต่อไปนี้

import { expose } from 'comlink';
import { marked } from 'marked';

class Compiler {
  state = {
    raw: '',
    compiled: '',
  };
  subscribers = [];

  async set(content) {
    this.state = {
      raw: content,
      compiled: marked(content),
    };

    await Promise.all(this.subscribers.map((s) => s(this.state)));
  }

  subscribe(cb) {
    this.subscribers.push(cb);
  }
}

const compiler = new Compiler();

onconnect = (e) => expose(compiler, e.ports[0]);

คำอธิบาย

โค้ดนี้จะตั้งค่าคลาสที่ชื่อ Compiler ซึ่งอนุญาตให้ตั้งค่าเนื้อหาและอนุญาตให้เรียกใช้การสมัครใช้บริการเมื่อคอมไพล์เนื้อหาแล้ว เนื่องจากเป็น Worker ที่แชร์ จึงควรใช้อินสแตนซ์เดียวของคลาสนี้ ดังนั้นจึงมีการสร้างอินสแตนซ์ใหม่ของ Compiler จากนั้นเราจะใช้ Comlink เพื่อแสดงอินสแตนซ์คอมไพเลอร์เพื่อให้การทำงานกับคลาสนี้เป็นไปอย่างราบรื่นจากภายนอก Worker ซึ่งจะช่วยให้เราใช้วิธีการทั้งหมดในคลาสนี้ได้ราวกับว่ามีการประกาศในโค้ดที่ใช้คลาสนี้ เนื่องจากเป็น SharedWorker แทนที่จะเป็น DedicatedWorker จึงต้องเปิดเผยต่อการเชื่อมต่อทั้งหมด

4. ส่งเนื้อหาไปยังผู้ปฏิบัติงาน

เมื่อสร้าง Worker แล้ว ตอนนี้เราต้องส่งเนื้อหาไปยัง Worker โดยอัปเดต js/main.js เพื่อทำสิ่งต่อไปนี้

คำอธิบาย

การห่อหุ้มการส่งออก Comlink ช่วยให้สามารถใช้สิ่งต่างๆ เช่น เมธอดของคลาสที่เปิดเผยได้ราวกับว่าไม่ได้แชร์ข้ามขอบเขตของ Worker โดยมีข้อยกเว้นคือตอนนี้ทุกอย่างเป็นแบบอะซิงโครนัส เนื่องจากเป็น Worker ที่แชร์แทนที่จะเป็น Worker เฉพาะ Comlink จึงต้องห่อหุ้มพอร์ตของ Worker แทนที่จะเป็นตัว Worker เอง ตอนนี้เมื่อใดก็ตามที่มีการอัปเดตเอดิเตอร์ ระบบจะส่งเนื้อหาไปยัง Worker เพื่อดำเนินการ

5. อัปเดตหน้าแสดงตัวอย่าง

ขั้นตอนสุดท้ายคือการนำเนื้อหาที่คอมไพล์แล้วออกจาก Worker ที่แชร์ไปยังตัวอย่าง การตั้งค่าเพื่อดำเนินการดังกล่าวจะเหมือนกันโดยส่วนใหญ่ แต่เนื่องจากฟังก์ชันไม่สามารถส่งผ่านขอบเขตของ Worker ได้ จึงต้องใช้พร็อกซีสำหรับฟังก์ชันแทน Comlink พร้อมให้ความช่วยเหลือคุณ อัปเดต js/preview.js เพื่อทำสิ่งต่อไปนี้

  • นำเข้าการส่งออกที่มีชื่อ wrap และ proxy จาก comlink
  • สร้างและรวม Worker ที่แชร์ตามที่คุณทำใน js/main.js
  • เรียกใช้เมธอด subscribe ของคอมไพเลอร์ด้วยฟังก์ชันพร็อกซีที่ตั้งค่าพร็อพเพอร์ตี้ compiled ของข้อมูลขาเข้าเป็น HTML ภายในของพื้นที่แสดงตัวอย่าง

เมื่อเสร็จแล้ว ให้เปิดตัวอย่าง เริ่มพิมพ์ในเครื่องมือแก้ไข แล้วสนุกและตื่นเต้นไปกับการดูมาร์กดาวน์ที่คอมไพล์โดยอัตโนมัติและปรากฏแบบเรียลไทม์ในพื้นที่แสดงตัวอย่าง ทั้งหมดนี้โดยไม่บล็อกเทรดหลักของทั้ง 2 หน้า

6. ยินดีด้วย

คุณได้เรียนรู้วิธีใช้ Shared Worker เพื่อแชร์สถานะระหว่างอินสแตนซ์ PWA หลายรายการแล้ว