1. ยินดีต้อนรับ
ในแล็บนี้ คุณจะได้ใช้เว็บแอปพลิเคชันที่มีอยู่แล้วและเพิ่ม Web Worker เพื่อแชร์สถานะระหว่างหน้าต่างที่เปิดอยู่ 2 หน้าต่าง นี่คือ Codelab ประกอบชุดที่ 8 สำหรับเวิร์กชอป Progressive Web App Codelab ก่อนหน้านี้คือ Service Worker Includes นี่คือโค้ดแล็บสุดท้ายในชุด
สิ่งที่คุณจะได้เรียนรู้
- เพิ่ม Worker ที่แชร์ระหว่างหน้าต่างที่เปิดอยู่หลายหน้าต่าง
- ใช้ Comlink เพื่อให้การทำงานร่วมกับ Worker ง่ายขึ้น
สิ่งที่ควรทราบ
- JavaScript
สิ่งที่คุณจะต้องมี
- เบราว์เซอร์ที่รองรับ Shared Web Workers
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
เพื่อทำสิ่งต่อไปนี้
- นำเข้าการส่งออกที่มีชื่อ
wrap
จากcomlink
- สร้าง Shared Worker ประเภทโมดูลใหม่ชื่อ
worker
ตั้งค่าประเภทเป็นmodule
และชี้ไปยัง Shared Worker โดยใช้รูปแบบnew URL
(new URL('./worker.js', import.meta.url)
) - สร้าง
compiler
ตัวแปรที่wrap
worker.port
- ในฟังก์ชันอัปเดตของเอดิเตอร์ (
editor.onUpdate
) หลังจากบันทึกเนื้อหาลงในฐานข้อมูลแล้ว ให้รอจนกว่าcompiler.set
จะเสร็จสิ้นโดยส่งเนื้อหา
คำอธิบาย
การห่อหุ้มการส่งออก 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 หลายรายการแล้ว