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};
ณ จุดนี้ การตั้งค่าต่อไปนี้จะถูกกำหนด:
-
createObjectStore
createObjectStore
เป็นเมธอดที่ใช้สร้าง 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
จะเก็บอินสแตนซ์ของฐานข้อมูลที่เปิดสำเร็จ (IDBDatabase
object) ซึ่งใช้ในการเริ่ม 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 ด้วย