ArrayBuffer sa TypeScript
Ipinaliliwanag ng artikulong ito ang ArrayBuffer sa TypeScript.
Ipapaliwanag namin ang ArrayBuffer sa TypeScript hakbang-hakbang, mula sa mga pangunahing konsepto hanggang sa mga praktikal na teknik.
YouTube Video
ArrayBuffer sa TypeScript
Ang ArrayBuffer ay isang built-in na object na kumakatawan sa 'hilaw na memory area' para sa binaryang datos. Ito ay isang hilaw na buffer na may fixed na haba, kung saan itinatambak ang TypedArray o DataView para sa pagbabasa at pagsusulat.
Mga Pangunahing Konsepto at Katangian ng ArrayBuffer
Ang ArrayBuffer ay isang sunud-sunod na bytes na may tiyak na haba. Itinatakda mo ang laki nito sa bytes kapag ginagawa, at hindi na maaaring baguhin ang haba nito pagkalikha.
1// Create a new ArrayBuffer of 16 bytes.
2const buf = new ArrayBuffer(16);
3console.log(buf.byteLength); // 16
- Ang code na ito ay lilikha ng isang bakanteng buffer na 16 bytes ang laki. Maaari mong tingnan ang laki nito gamit ang
byteLength.
TypedArray at DataView — Mga View para sa Pag-manipula ng mga Buffer
Ang ArrayBuffer ay walang kakayahan na magbasa o magsulat ng data. Dahil dito, ang aktwal na operasyon ay isinasagawa gamit ang TypedArray o DataView, kung saan tinutukoy ang mga tipo gaya ng integer o floating-point at endianness kapag ina-access ang data.
1// Create a buffer and a Uint8Array view over it. Then write bytes and read them.
2const buffer = new ArrayBuffer(8);
3const u8 = new Uint8Array(buffer);
4
5u8[0] = 0x41; // 'A'
6u8[1] = 0x42; // 'B'
7console.log(u8); // Uint8Array(8) [ 65, 66, 0, 0, 0, 0, 0, 0 ]
- Ang
Uint8Arrayay isang byte-wise na array view, at maaari itong gamitin parang karaniwang array. Kung maglalagay ka ng maraming views sa parehongArrayBuffer, magbabahagi sila ng iisang memorya para sa pagbabasa at pagsusulat.
DataView: Pagbabasa at Pagsusulat sa Nais na Hangganan at Endianness
Ang DataView ay kapaki-pakinabang para sa detalyadong pagbabasa at pagsusulat batay sa byte, at nagbibigay-daan upang tukuyin ang little o big endian.
1// Using DataView to write/read multi-byte values with endianness control.
2const buf2 = new ArrayBuffer(8);
3const view = new DataView(buf2);
4
5// Write a 32-bit integer (little-endian)
6view.setInt32(0, 0x12345678, true);
7
8// Read it back as little-endian and big-endian
9const little = view.getInt32(0, true);
10const big = view.getInt32(0, false);
11console.log(little.toString(16)); // "12345678"
12console.log(big.toString(16)); // "78563412"
- Pinapayagan ka ng
DataViewna magbasa at magsulat ng mga value sa pamamagitan ng pagtukoy ng offset sa memorya, kaya ito ay angkop para sa pagpapatupad ng mga protocol na nangangailangan ng paghawak ng network byte order.
Pag-convert sa pagitan ng Strings at ArrayBuffer (TextEncoder / TextDecoder)
Upang i-convert ang teksto sa binary at pabalik, gamitin ang TextEncoder at TextDecoder.
1// Convert string -> ArrayBuffer and back using TextEncoder/TextDecoder.
2const encoder = new TextEncoder();
3const decoder = new TextDecoder();
4
5// Unicode escape sequences
6const str = "\u3053\u3093\u306B\u3061\u306F";
7const encoded = encoder.encode(str); // Uint8Array
8console.log(encoded); // Uint8Array([...])
9
10// If you need an ArrayBuffer specifically:
11const ab = encoded.buffer.slice(encoded.byteOffset, encoded.byteOffset + encoded.byteLength);
12console.log(ab.byteLength); // bytes length of encoded text
13
14// Decode back
15const decoded = decoder.decode(encoded);
16console.log(decoded);- Ang
TextEncoder.encodeay nagbabalik ngUint8Array, kaya kung kailangan mo ngArrayBuffer, dapat mong gamitin ang.bufferproperty nito. Sa pamamagitan ngslicemethod, maaari mong kunin ang kinakailangang data sa pamamagitan ng pagtukoy ng offset at haba.
Paghiwa-hiwa at Pagkopya ng ArrayBuffer
Ang slice method ay nagbabalik ng bagong ArrayBuffer. Ang ArrayBuffer ay hindi maaaring palakihin o paliitin; kung kailangan ito, lumikha ng bagong buffer at kopyahin ang data dito.
1// Slice an ArrayBuffer and copy to a new sized buffer.
2const original = new Uint8Array([1,2,3,4,5]).buffer;
3const part = original.slice(1, 4); // bytes 1..3
4console.log(new Uint8Array(part)); // Uint8Array [ 2, 3, 4 ]
5
6// Resize: create a new buffer and copy existing content
7const larger = new ArrayBuffer(10);
8const target = new Uint8Array(larger);
9target.set(new Uint8Array(original), 0);
10console.log(target); // first bytes filled with original data
- Dahil ang
slicemethod ay nagbabalik ng bagongArrayBuffer, kung inuuna mo ang pagiging epektibo o paghahati ng reference, maaari mong gamitin angsubarraymethod ngTypedArrayupang tumukoy sa parehong buffer.
Pagkakaiba ng TypedArray.subarray at Pagkopya
Ang subarray ng TypedArray ay nagbibigay ng bagong view na tumutukoy pa rin sa parehong ArrayBuffer.
1// subarray shares the same underlying buffer; modifying one affects the other.
2const arr = new Uint8Array([10,20,30,40]);
3const viewSub = arr.subarray(1,3); // shares memory
4viewSub[0] = 99;
5console.log(arr); // Uint8Array [10, 99, 30, 40]
- Ang shared views ay makakaiwas sa gastos ng pagkopya, ngunit dahil tumutukoy sila sa parehong buffer, kailangan mong mag-ingat sa mga side effect.
Pagkakadugtong ng mga Buffer (Pagsasama-sama ng maraming ArrayBuffer)
Dahil ang ArrayBuffer ay may fixed na haba, kailangan gumawa ng bagong ArrayBuffer at kopyahin ang data para mapagsama-sama ang mga buffer.
1// Concatenate multiple ArrayBuffers
2function concatBuffers(buffers: ArrayBuffer[]): ArrayBuffer {
3 const total = buffers.reduce((sum, b) => sum + b.byteLength, 0);
4 const result = new Uint8Array(total);
5 let offset = 0;
6 for (const b of buffers) {
7 const u8 = new Uint8Array(b);
8 result.set(u8, offset);
9 offset += u8.length;
10 }
11 return result.buffer;
12}
13
14const a = new Uint8Array([1,2]).buffer;
15const b = new Uint8Array([3,4,5]).buffer;
16const c = concatBuffers([a, b]);
17console.log(new Uint8Array(c)); // [1,2,3,4,5]
- Kung madalas kang magdugtong ng maraming data, mas mahusay na kwentahin muna ang kabuuang laki at maglaan ng bagong buffer isang beses lang, gaya ng nasa code na ito.
Pagpapasa ng ArrayBuffer sa isang Worker (Transferable)
Sa postMessage ng browser, maaari mong ilipat ang isang ArrayBuffer bilang isang "transferable" na object. Maaaring ilipat ang pagmamay-ari nang hindi kinakailangang kopyahin, na nakakaiwas sa gastos ng pagkopya.
1// Example: posting an ArrayBuffer to a Worker as a transferable object (browser)
2const worker = new Worker('worker.js');
3const bufferToSend = new Uint8Array([1,2,3,4]).buffer;
4
5// Transfer ownership to the worker (main thread no longer owns it)
6worker.postMessage(bufferToSend, [bufferToSend]);
7
8// After transfer, bufferToSend.byteLength === 0 in many browsers (detached)
9console.log(bufferToSend.byteLength); // may be 0
- Sa pamamagitan ng pagtukoy ng mga object na ililipat sa isang array bilang ikalawang argumento ng
postMessage, maaari mong ilipat ang pagmamay-ari ng mga transferable na object gaya ngArrayBuffernang hindi kinakailangang kopyahin. - Pagkatapos ng paglilipat, ang buffer ay nagiging "detached" sa orihinal na bahagi at hindi na ito maa-access. Ang paggamit ng
SharedArrayBufferay nagpapahintulot sa sabayang pag-access mula sa maraming thread, ngunit ito ay may kasamang mga kinakailangan sa seguridad at mga limitasyon sa kapaligiran.
Paggamit sa Node.js (Pag-convert sa pagitan ng Buffer at ArrayBuffer)
Sa Node.js, maaari kang mag-convert sa pagitan ng Node.js binary type na Buffer at ArrayBuffer. Kapaki-pakinabang ito kung pareho mong tina-target ang browser at Node.js gamit ang TypeScript.
1// Convert ArrayBuffer <-> Node.js Buffer
2// In Node.js environment:
3const ab = new Uint8Array([10,20,30]).buffer;
4const nodeBuffer = Buffer.from(ab); // ArrayBuffer -> Buffer
5console.log(nodeBuffer); // <Buffer 0a 14 1e>
6
7const backToAb = nodeBuffer.buffer.slice(
8 nodeBuffer.byteOffset,
9 nodeBuffer.byteOffset + nodeBuffer.byteLength
10);
11console.log(new Uint8Array(backToAb)); // Uint8Array [10,20,30]
Buffer.from(arrayBuffer)sa Node.js ay karaniwang gumagawa ng kopya, ngunit may mga pagkakataon ding nakakapagbahagi ng reference, kaya mag-ingat sa paggamit ng offset.
Mga Paalaala sa Performance at Mga Pinakamainam na Gawi
Para mapahusay ang performance at mahusay na magamit ang ArrayBuffer, may ilang importanteng bagay na dapat tandaan. Nasa ibaba ang ilang praktikal na pinakamainam na gawi at pagpapaliwanag ng mga ito.
-
Bawasan ang Dami ng Pagkopya Kapag humahawak ng malalaking binary, gamitin ang
subarray(shared view) o transferables upang mabawasan ang pagkopya. -
Maglaan ng Malalaking Buffers ng Sabay-sabay Ang paulit-ulit na paglalaan ng maliliit na buffer ay nagpapataas ng overhead. Kung maaari, maglaan ng malaking buffer nang sabay-sabay at gamitin lamang ang mga bahagi nito kung kinakailangan.
-
Tukuyin nang malinaw ang Endianness Kapag humahawak ng multibyte na halaga, gamitin ang
DataViewat malinaw na tukuyin ang endianness. Madaling maging standard ang big-endian para sa mga network protocol.
Karaniwang Halimbawa ng Paggamit
Malawakang ginagamit ang ArrayBuffer sa parehong browser at Node.js.
- Pag-parse at paggawa ng binary protocols (pagpoproseso ng header information gamit ang
DataView) - Pagpoproseso ng media gaya ng larawan at audio (
fetch(...).then(res => res.arrayBuffer())) - Shared memory para sa WebAssembly (Ang memory ng Wasm ay nakabatay sa
ArrayBuffer) - Pag-offload ng mabibigat na proseso sa Workers (pagpasa ng
ArrayBufferbilang transferable)
Ang sumusunod na code ay halimbawa ng pagkuha at pagsusuri ng binaryang datos.
1// Example: fetch binary data in browser and inspect first bytes
2async function fetchAndInspect(url: string) {
3 const resp = await fetch(url);
4 const ab = await resp.arrayBuffer();
5 const u8 = new Uint8Array(ab, 0, Math.min(16, ab.byteLength));
6 console.log('first bytes:', u8);
7}- Kinukuha ng code na ito ang binaryang datos mula sa anumang URL sa browser at ipinapakita ang ilang unang bytes. Ikinakarga ng code ang data na nakuha gamit ang
fetchAPI bilang isangArrayBufferat pinagmamasdan ang unang 16 na bytes gamit angUint8Array.
Buod
Ang ArrayBuffer ay isang anyo ng hilaw na memory, na nagpapagaan ng mas mabilis na binary operations sa pamamagitan ng TypedArray at DataView. Kung magdidisenyo ka para maiwasan ang hindi kailangang pagkopya at malinaw magtukoy ng endianness, makakamtan mo ang ligtas at mataas na performance na binary processing.
Maaari mong sundan ang artikulo sa itaas gamit ang Visual Studio Code sa aming YouTube channel. Paki-check din ang aming YouTube channel.