JavaScript และ IndexedDB
ในบทความนี้ เราจะอธิบายเกี่ยวกับ JavaScript และ IndexedDB
บทแนะนำนี้จะอธิบายเกี่ยวกับ JavaScript และ IndexedDB แบบทีละขั้นตอน พร้อมด้วยตัวอย่างโค้ดที่ปฏิบัติได้จริงในแต่ละขั้น เพื่อช่วยให้คุณเข้าใจลึกซึ้งยิ่งขึ้น
YouTube Video
javascript-indexed-db.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>JavaScript & HTML</title>
6 <style>
7 * {
8 box-sizing: border-box;
9 }
10
11 body {
12 margin: 0;
13 padding: 1em;
14 padding-bottom: 10em;
15 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
16 background-color: #f7f9fc;
17 color: #333;
18 line-height: 1.6;
19 }
20
21 .container {
22 max-width: 800px;
23 margin: 0 auto;
24 padding: 1em;
25 background-color: #ffffff;
26 border: 1px solid #ccc;
27 border-radius: 10px;
28 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
29 }
30
31 .container-flex {
32 display: flex;
33 flex-wrap: wrap;
34 gap: 2em;
35 max-width: 1000px;
36 margin: 0 auto;
37 padding: 1em;
38 background-color: #ffffff;
39 border: 1px solid #ccc;
40 border-radius: 10px;
41 box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
42 }
43
44 .left-column, .right-column {
45 flex: 1 1 200px;
46 min-width: 200px;
47 }
48
49 h1, h2 {
50 font-size: 1.2rem;
51 color: #007bff;
52 margin-top: 0.5em;
53 margin-bottom: 0.5em;
54 border-left: 5px solid #007bff;
55 padding-left: 0.6em;
56 background-color: #e9f2ff;
57 }
58
59 button {
60 display: block;
61 margin: 1em auto;
62 padding: 0.75em 1.5em;
63 font-size: 1rem;
64 background-color: #007bff;
65 color: white;
66 border: none;
67 border-radius: 6px;
68 cursor: pointer;
69 transition: background-color 0.3s ease;
70 }
71
72 button:hover {
73 background-color: #0056b3;
74 }
75
76 #output {
77 margin-top: 1em;
78 background-color: #1e1e1e;
79 color: #0f0;
80 padding: 1em;
81 border-radius: 8px;
82 min-height: 200px;
83 font-family: Consolas, monospace;
84 font-size: 0.95rem;
85 overflow-y: auto;
86 white-space: pre-wrap;
87 }
88
89 .highlight {
90 outline: 3px solid #ffc107; /* yellow border */
91 background-color: #fff8e1; /* soft yellow background */
92 transition: background-color 0.3s ease, outline 0.3s ease;
93 }
94
95 .active {
96 background-color: #28a745; /* green background */
97 color: #fff;
98 box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
99 transition: background-color 0.3s ease, box-shadow 0.3s ease;
100 }
101 </style>
102</head>
103<body>
104 <div class="container">
105 <h1>JavaScript Console</h1>
106 <button id="executeBtn">Execute</button>
107 <div id="output"></div>
108 </div>
109
110 <script>
111 // Override console.log to display messages in the #output element
112 (function () {
113 // Override console.log
114 const originalLog = console.log;
115 console.log = function (...args) {
116 originalLog.apply(console, args);
117 const message = document.createElement('div');
118 message.textContent = args
119 .map(arg => (typeof arg === "object" && arg !== null ? JSON.stringify(arg) : String(arg)))
120 .join(" ");
121 output.appendChild(message);
122 };
123
124 // Override console.error
125 const originalError = console.error;
126 console.error = function (...args) {
127 originalError.apply(console, args);
128 const message = document.createElement('div');
129 message.textContent = args
130 .map(arg => (typeof arg === "object" && arg !== null ? JSON.stringify(arg) : String(arg)))
131 .join(" ");
132 message.style.color = 'red'; // Color error messages red
133 output.appendChild(message);
134 };
135 })();
136
137 document.getElementById('executeBtn').addEventListener('click', () => {
138 // Prevent multiple loads
139 if (document.getElementById('externalScript')) return;
140
141 const script = document.createElement('script');
142 script.src = 'javascript-indexed-db.js';
143 script.id = 'externalScript';
144 //script.onload = () => console.log('javascript-indexed-db.js loaded and executed.');
145 //script.onerror = () => console.log('Failed to load javascript-indexed-db.js.');
146 document.body.appendChild(script);
147 });
148 </script>
149</body>
150</html>JavaScript และ IndexedDB
IndexedDB เป็นฐานข้อมูล key-value แบบ asynchronous ที่ฝังอยู่ในเบราว์เซอร์ มันมีฟีเจอร์คล้ายกับฐานข้อมูลเชิงสัมพันธ์ และช่วยให้คุณสามารถเก็บและค้นหาข้อมูลขนาดใหญ่แบบมีโครงสร้างบนฝั่งไคลเอนต์ โดยเฉพาะเหมาะสำหรับแอปพลิเคชันที่รองรับออฟไลน์ และ PWAs (Progressive Web Apps)
คุณสมบัติของ IndexedDB
- ทำงานแบบ asynchronous และ event-driven
- อ็อบเจกต์ JavaScript สามารถเก็บไว้ใน object stores
- สามารถค้นหาด้วย query หรือดัชนี (index) ได้
- มีความจุในการจัดเก็บสูง (หลักร้อย MB ขึ้นไป) สามารถเก็บข้อมูลได้มากกว่าคุกกี้หรือ localStorage
การเปิดและสร้างฐานข้อมูล
ในการใช้ IndexedDB จำเป็นต้องเปิดฐานข้อมูลก่อน ถ้าฐานข้อมูลยังไม่มี จะถูกสร้างโดยอัตโนมัติ
1const request = indexedDB.open('MyDatabase', 1); // Specify DB name and version
- เมธอด
openจะเปิดฐานข้อมูลแบบ asynchronous และทำให้เกิด event 3 อย่างดังนี้
onsuccess
1// Fired when database is successfully opened
2request.onsuccess = (event) => {
3 const db = event.target.result; // Database instance
4 console.log('Database opened successfully:', db.name);
5};- event
onsuccessจะถูกเรียกเมื่อฐานข้อมูลเปิดสำเร็จ การดำเนินการขั้นต่อไปควรใช้request.resultซึ่งจะใช้ได้ในขณะนี้
onerror
1// Fired when database fails to open
2request.onerror = (event) => {
3 console.error('Failed to open database:', event.target.error);
4};- event
onerrorจะถูกเรียกเมื่อเปิดฐานข้อมูลล้มเหลว ควรดำเนินการบันทึกข้อผิดพลาดและจัดการข้อผิดพลาดที่นี่
onupgradeneeded
1// Fired when database is newly created or upgraded
2request.onupgradeneeded = (event) => {
3 const db = event.target.result;
4 console.log('Database upgrade needed (or newly created):', db.name);
5
6 // Example: Create an object store (like a table) if it doesn’t exist
7 if (!db.objectStoreNames.contains('users')) {
8 db.createObjectStore('users', { keyPath: 'id' });
9 console.log('Object store "users" created');
10 }
11};- event
onupgradeneededจะถูกเรียกเมื่อสร้างฐานข้อมูลใหม่หรือเปลี่ยนเวอร์ชันที่สูงกว่าของเดิม การสร้างตาราง (object stores) และกำหนด schema ควรกระทำในช่วงเวลานี้
การสร้าง Object Store
ขั้นแรก ให้สร้าง 'object store' (เทียบได้กับตาราง) ภายใน onupgradeneeded
1request.onupgradeneeded = function (event) {
2 const db = event.target.result;
3 console.log("onupgradeneeded triggered. Database version:", db.version);
4 if (!db.objectStoreNames.contains('users')) {
5 console.log("Creating object store: users");
6 const store = db.createObjectStore('users', { keyPath: 'id' });
7 store.createIndex('name', 'name', { unique: false });
8 }
9};ณ จุดนี้ การตั้งค่าต่อไปนี้จะถูกกำหนด:
-
createObjectStorecreateObjectStoreเป็นเมธอดที่ใช้สร้าง object store ใหม่ภายในฐานข้อมูล คุณสามารถเก็บ record ต่าง ๆ ไว้ใน object store และกำหนดวิธีการจัดการข้อมูลผ่านkeyPathและออปชั่นอื่น ๆ กระบวนการนี้ต้องทำภายใน eventonupgradeneeded -
keyPath: 'id'กำหนดkeyPathให้ชี้ไปที่ propertyidซึ่งเป็น primary key ที่ใช้ระบุความเป็นเอกลักษณ์ของแต่ละ record การตั้งค่านี้จะทำให้สามารถใช้idโดยอัตโนมัติเมื่อเพิ่ม ค้นหา หรืออัปเดตข้อมูล -
createIndexใช้เมธอดcreateIndexเพื่อสร้างดัชนี (index) จาก propertynameสำหรับค้นหา การตั้งค่าunique: falseจะอนุญาตให้มี record ที่nameซ้ำกันได้หลายรายการ
การจัดการเมื่อเชื่อมต่อฐานข้อมูลสำเร็จ
กำหนดกระบวนการที่ต้องดำเนินการเมื่อเชื่อมต่อฐานข้อมูลสำเร็จให้กับ event onsuccess ภายในกระบวนการนี้ คุณจะได้รับอินสแตนซ์ของฐานข้อมูล และเตรียมสำหรับดำเนินการอ่าน/เขียนข้อมูล
1request.onsuccess = function (event) {
2 const db = event.target.result;
3 console.log('Database opened successfully');
4 // Use db for reading and writing in subsequent operations
5};-
กระบวนการนี้จะทำงานเมื่อเชื่อมต่อฐานข้อมูล
IndexedDBสำเร็จ -
event.target.resultจะเก็บอินสแตนซ์ของฐานข้อมูลที่เปิดสำเร็จ (IDBDatabaseobject) ซึ่งใช้ในการเริ่ม transaction และเข้าถึง object store ต่างๆ -
กระบวนการอ่านและเขียนจริง เช่น การเพิ่ม ค้นหา อัปเดต และลบข้อมูล จะกระทำโดยใช้วัตถุ
db
ในขณะนี้ ฐานข้อมูลพร้อมใช้งานแล้ว คุณสามารถเริ่ม transaction ได้อย่างปลอดภัย
การเพิ่มข้อมูล
วิธีการเพิ่มข้อมูลใหม่ไปยัง IndexedDB มีดังนี้
1function addUser(db, user) {
2 const transaction = db.transaction('users', 'readwrite');
3 const store = transaction.objectStore('users');
4 const request = store.add(user);
5
6 request.onsuccess = () => {
7 console.log('User added:', user);
8 };
9
10 request.onerror = () => {
11 console.error('Add failed:', request.error);
12 };
13}
14
15// Example: Add a user
16request.onsuccess = function (event) {
17 const db = event.target.result;
18 addUser(db, { id: 1, name: 'Alice' });
19 addUser(db, { id: 2, name: 'Bob' });
20 addUser(db, { id: 3, name: 'John' });
21};- สร้าง transaction ด้วย
db.transaction()ระบุ object store ที่ต้องการดำเนินการ และระบุโหมด (ในกรณีนี้คือreadwrite) - เพิ่มข้อมูลใหม่โดยใช้เมธอด
store.add() - Transaction จะถูก commit โดยอัตโนมัติ แต่หากคุณต้องการรวมหลาย ๆ กระบวนการเข้าด้วยกัน สามารถจัดการได้ผ่าน event หลัง transaction สิ้นสุด
การเรียกดูข้อมูล (ค้นหาด้วย Primary Key)
วิธีการเรียกข้อมูลแต่ละรายการด้วย primary key มีดังนี้
1function getUserById(db, id) {
2 const transaction = db.transaction('users', 'readonly');
3 const store = transaction.objectStore('users');
4 const request = store.get(id);
5
6 request.onsuccess = () => {
7 if (request.result) {
8 console.log('User found:', request.result);
9 } else {
10 console.log('User not found');
11 }
12 };
13
14 request.onerror = () => {
15 console.error('Error retrieving user:', request.error);
16 };
17}
18
19// Example: Get a user by id
20request.onsuccess = function (event) {
21 const db = event.target.result;
22 getUserById(db, 1);
23};- สร้าง transaction แบบ read-only ด้วย
db.transaction() - ใช้
store.get(id)เพื่อดึงข้อมูลที่ตรงกับ primary key ที่ระบุไว้ - เมื่อดึงข้อมูลสำเร็จ
onsuccessจะถูกเรียก และแสดงผลลัพธ์หากมีข้อมูล ถ้าไม่มีผลลัพธ์ จะถือว่า 'ไม่มีข้อมูลที่ตรงกัน'
การค้นหาโดยใช้ Index
หากต้องการค้นหาด้วย property อื่นที่ไม่ใช่ primary key ให้ใช้ index ที่สร้างขึ้นไว้ก่อนหน้า
1function getUserByName(db, name) {
2 const transaction = db.transaction('users', 'readonly');
3 const store = transaction.objectStore('users');
4 const index = store.index('name');
5 const request = index.get(name);
6
7 request.onsuccess = () => {
8 if (request.result) {
9 console.log('User by name:', request.result);
10 } else {
11 console.log('No user found with that name');
12 }
13 };
14
15 request.onerror = () => {
16 console.error('Error retrieving user by name:', request.error);
17 };
18}
19
20// Example: Get a user by id
21request.onsuccess = function (event) {
22 const db = event.target.result;
23 getUserByName(db, 'Alice');
24};- เข้าถึง index
nameที่สร้างไว้ล่วงหน้าด้วยstore.index('name') index.get(value)จะดึง record ตัวแรกที่ค่าตรงกับที่ระบุ ถ้ามี record หลายรายการที่ค่าตรงกัน สามารถดึงทั้งหมดได้ด้วยindex.getAll(value)
การอัปเดตข้อมูล
ในการอัปเดต (เขียนทับ) ข้อมูลเดิม ให้ใช้เมธอด put()
หากมี record ที่ primary key ตรงกัน ข้อมูลจะถูกอัปเดต ถ้าไม่มีก็จะเพิ่ม record ใหม่
1function updateUser(db, updatedUser) {
2 const transaction = db.transaction('users', 'readwrite');
3 const store = transaction.objectStore('users');
4 const request = store.put(updatedUser);
5
6 request.onsuccess = () => {
7 console.log('User updated:', updatedUser);
8 };
9
10 request.onerror = () => {
11 console.error('Update failed:', request.error);
12 };
13}
14
15// Example: Update user
16request.onsuccess = async (event) => {
17 const db = event.target.result;
18
19 // Test : update existing user
20 updateUser(db, { id: 3, name: 'John Updated' });
21
22 // Test : insert new user
23 updateUser(db, { id: 4, name: 'Charlie' });
24};put()เป็นเมธอดที่สะดวก เพราะรองรับทั้งการอัปเดตและการเพิ่มข้อมูล- ถ้ามีข้อมูลที่ primary key เดียวกันอยู่แล้ว จะถูกเขียนทับ
- หากต้องการตรวจสอบการมีอยู่ก่อนอัปเดต สามารถใช้
get()เพื่อตรวจสอบล่วงหน้าได้
การลบข้อมูล
ในการลบข้อมูลที่ตรงกับ primary key ให้ใช้เมธอด delete()
1function deleteUser(db, id) {
2 const transaction = db.transaction('users', 'readwrite');
3 const store = transaction.objectStore('users');
4 const request = store.delete(id);
5
6 request.onsuccess = () => {
7 console.log(`User with id=${id} deleted successfully`);
8 };
9
10 request.onerror = () => {
11 console.error(`Failed to delete user with id=${id}:`, request.error);
12 };
13}
14
15// Example: Delete a user by id
16request.onsuccess = function (event) {
17 const db = event.target.result;
18 deleteUser(db, 4);
19};- ใช้
store.delete(id)เพื่อลบข้อมูลที่ primary key ตรงกัน - โปรดทราบ แม้ว่าข้อมูลจะไม่มีอยู่จริงก็ไม่เกิดข้อผิดพลาด และนับว่าประสบความสำเร็จ
- การเพิ่มการจัดการข้อผิดพลาดจะช่วยให้โค้ดมีความเสถียรยิ่งขึ้น
การเรียกดูข้อมูลทั้งหมด
getAll()
หากต้องการดึง record ทั้งหมดใน object store ให้ใช้เมธอด getAll()
1function getAllUsers(db) {
2 const transaction = db.transaction('users', 'readonly');
3 const store = transaction.objectStore('users');
4 const request = store.getAll();
5
6 request.onsuccess = () => {
7 console.log('All users:', request.result);
8 };
9
10 request.onerror = () => {
11 console.error('Failed to retrieve users:', request.error);
12 };
13}
14
15// Example: Get all users
16request.onsuccess = function (event) {
17 const db = event.target.result;
18 getAllUsers(db);
19};getAll()จะดึงข้อมูลทุก record ใน object store ที่ระบุมาเป็น array- แม้จะดึงข้อมูลจำนวนมากในครั้งเดียวก็จะถูกประมวลผลอย่างมีประสิทธิภาพ
- ผลลัพธ์จะถูกเก็บในรูปแบบ array ที่
request.result - ควรใส่ขั้นตอนสำหรับจัดการข้อผิดพลาดเสมอ เพื่อรองรับกรณีเกิดความล้มเหลว
openCursor()
openCursor() เป็นเมธอดสำหรับ เดินรายการข้อมูลทีละ record ใน object store หรือ index เหมาะกับกรณีที่ต้องการประมวลผลข้อมูลทีละรายการ ไม่ใช่ดึงทั้งหมดในคราวเดียว
1function getAllUsersWithCursor(db) {
2 const transaction = db.transaction('users', 'readonly');
3 const store = transaction.objectStore('users');
4 const request = store.openCursor();
5
6 request.onsuccess = () => {
7 const cursor = request.result;
8 if (cursor) {
9 console.log('User:', cursor.value); // Process the current record
10 cursor.continue(); // Move to the next record
11 } else {
12 console.log('All users have been processed.');
13 }
14 };
15
16 request.onerror = () => {
17 console.error('Failed to open cursor:', request.error);
18 };
19}
20
21// Example: Get all users
22request.onsuccess = function (event) {
23 const db = event.target.result;
24 getAllUsersWithCursor(db);
25};- โดยใช้
openCursor()คุณจะเริ่มเปิด cursor และดึงข้อมูลใน object store ทีละรายการ - ใช้
cursor.valueเพื่อดึงอ็อบเจกต์ข้อมูลของ record ปัจจุบัน - ขยับ cursor ไปยัง record ถัดไปด้วย
cursor.continue() - เมื่อ
cursor === nullหมายถึงได้เดินครบทุกข้อมูลแล้ว
ตัวอย่างกระบวนการอัปเดตโดยใช้ openCursor()
ตัวอย่างเช่น กระบวนการเปลี่ยนชื่่อผู้ใช้ที่มี name เป็น Alice เป็น Alicia จะมีลักษณะดังนี้:
1function updateUserName(db, oldName, newName) {
2 const transaction = db.transaction('users', 'readwrite');
3 const store = transaction.objectStore('users');
4 const index = store.index('name'); // Use the 'name' index
5 const request = index.openCursor(IDBKeyRange.only(oldName));
6
7 request.onsuccess = () => {
8 const cursor = request.result;
9 if (cursor) {
10 const user = cursor.value;
11 user.name = newName; // Update the name
12 const updateRequest = cursor.update(user);
13
14 updateRequest.onsuccess = () => {
15 console.log('Updated user:', user);
16 };
17
18 updateRequest.onerror = () => {
19 console.error('Failed to update user:', updateRequest.error);
20 };
21
22 cursor.continue();
23 } else {
24 console.log('All matching users have been updated.');
25 }
26 };
27
28 request.onerror = () => {
29 console.error('Cursor error:', request.error);
30 };
31}
32
33// Example: Update user name
34request.onsuccess = function (event) {
35 const db = event.target.result;
36 updateUserName(db, 'Alice', 'Alicia');
37};-
IDBKeyRange.only(oldName)โดยการใช้IDBKeyRange.onlyคุณสามารถเจาะจงเฉพาะเรคคอร์ดที่มีคีย์ตรงกับoldNameได้ สิ่งนี้มีประโยชน์เมื่อคุณต้องการเข้าถึงค่าที่ระบุโดยตรง -
cursor.update()หลังจากอัปเดตcursor.valueแล้ว การเรียกใช้update()จะเขียนทับเรคคอร์ดที่เกี่ยวข้อง -
การจัดการกรณีตรงกันหลายรายการ โดยการเรียกใช้
cursor.continue()คุณสามารถเลื่อนเคอร์เซอร์ไปยังเรคคอร์ดถัดไปที่ตรงกัน สิ่งนี้จะช่วยให้คุณสามารถประมวลผลเรคคอร์ดหลายรายการที่ตรงกับคีย์หรือเงื่อนไขเดียวกันได้อย่างต่อเนื่อง -
การจัดการข้อผิดพลาด โดยการบันทึก log ใน
onerrorเมื่อกระบวนการเกิดข้อผิดพลาด จะช่วยให้ง่ายต่อการตรวจสอบและแก้ไขปัญหาระหว่างการทำงาน
ตัวอย่างกระบวนการลบโดยใช้ openCursor()
ตัวอย่างเช่น กระบวนการลบผู้ใช้ทั้งหมดที่มี name เป็น Bob จะมีลักษณะดังนี้:
1function deleteUsersByName(db, targetName) {
2 const transaction = db.transaction('users', 'readwrite');
3 const store = transaction.objectStore('users');
4 const index = store.index('name');
5 const request = index.openCursor(IDBKeyRange.only(targetName));
6
7 request.onsuccess = () => {
8 const cursor = request.result;
9 if (cursor) {
10 const deleteRequest = cursor.delete();
11
12 deleteRequest.onsuccess = () => {
13 console.log('Deleted user:', cursor.value);
14 };
15
16 deleteRequest.onerror = () => {
17 console.error('Failed to delete user:', deleteRequest.error);
18 };
19
20 cursor.continue();
21 } else {
22 console.log('All matching users have been deleted.');
23 }
24 };
25
26 request.onerror = () => {
27 console.error('Cursor error:', request.error);
28 };
29}
30
31// Example: Delete user by name
32request.onsuccess = function (event) {
33 const db = event.target.result;
34 deleteUsersByName(db, 'Bob');
35};cursor.delete()เมื่อใช้cursor.delete()เรคคอร์ดที่ตำแหน่งปัจจุบันของเคอร์เซอร์จะถูกลบ เนื่องจากผลลัพธ์จะถูกส่งกลับแบบอัสินโครนัส คุณสามารถตรวจสอบกระบวนการในonsuccessได้
หมายเหตุเกี่ยวกับธุรกรรมและการประมวลผลแบบอัสินโครนัส
IndexedDB เป็นแบบอัสินโครนัสและทำงานตามเหตุการณ์ (event-driven) ต้องดำเนินการกับทุกฟังก์ชันด้วยเหตุการณ์ onsuccess หรือ onerror เมื่อคุณต้องการจัดกลุ่มกระบวนการหลายรายการเข้าด้วยกัน การนำมาห่อรวมใน Promise จะสะดวกมาก
1function openDatabase() {
2 return new Promise((resolve, reject) => {
3 const request = indexedDB.open('MyDatabase', 1);
4
5 request.onupgradeneeded = function (event) {
6 const db = event.target.result;
7
8 // Initialization process (creating object stores and indexes, etc.)
9 const store = db.createObjectStore('users', { keyPath: 'id' });
10 store.createIndex('name', 'name', { unique: false });
11 };
12
13 request.onsuccess = function (event) {
14 const db = event.target.result;
15 resolve(db);
16 };
17
18 request.onerror = function () {
19 reject(request.error);
20 };
21 });
22}
23
24function addUserAsync(db, user) {
25 return new Promise((resolve, reject) => {
26 const transaction = db.transaction('users', 'readwrite');
27 const store = transaction.objectStore('users');
28 const request = store.add(user);
29
30 request.onsuccess = () => resolve();
31 request.onerror = () => reject(request.error);
32 });
33}
34
35async function main() {
36 try {
37 const db = await openDatabase();
38 await addUserAsync(db, { id: 1, name: 'Alice' });
39 console.log('User added successfully');
40 } catch (error) {
41 console.error('Error:', error);
42 }
43}- ห่อหุ้มฟังก์ชันเช่น
openDatabaseหรือaddUserAsyncด้วยPromiseจะช่วยให้คุณสามารถจัดการกับกระบวนการแบบอัสินโครนัสได้อย่างเป็นธรรมชาติด้วยasync/await - สิ่งนี้ช่วยหลีกเลี่ยงปัญหา callback hell และทำให้โค้ดอ่านง่ายขึ้น
สรุป
IndexedDB เป็นฟีเจอร์ที่มีประสิทธิภาพมากเมื่อคุณต้องการจัดการข้อมูลขั้นสูงที่ฝั่งเบราว์เซอร์ ในตอนแรก คุณอาจสับสนกับการประมวลผลแบบอัสินโครนัสที่อิงตามเหตุการณ์ แต่เมื่อเข้าใจโครงสร้างแล้ว คุณจะสามารถดำเนินการจัดการข้อมูลขนาดใหญ่ที่ฝั่งไคลเอนต์ได้
โดยเฉพาะอย่างยิ่ง หากคุณคำนึงถึงจุดต่อไปนี้ จะทำให้คุณใช้งานได้อย่างราบรื่นมากขึ้น:
- ในการตั้งค่าเริ่มต้น ให้ใช้
onupgradeneeded - ให้ความสำคัญกับโหมดอ่าน/เขียนของธุรกรรม
- การใช้ดัชนี (Index) ช่วยให้ค้นหาได้อย่างมีประสิทธิภาพ
- ข้อมูลสามารถเก็บในรูปแบบอ็อบเจ็กต์ ซึ่งเข้ากันได้ดีกับ JSON
ด้วยการใช้งาน IndexedDB อย่างชำนาญ การบริหารจัดการข้อมูลสำหรับ PWA และแอปออฟไลน์จะง่ายขึ้นมาก
คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย