JS Streams
JavaScript Asenkron Programlama konusunda önemli bir diğer konuda Streams yani büyük verilerin bir yerden diğerine akışının nasıl gerçekleştiği konusudur. Bu blog yazısında farklı kullanım senaryoları üzerinden bu akışları inceleyeceğiz.
JavaScript’te streams verilerin parça parça işlendiği ve gerektiğinde kullanıldığı bir modeli ifade eder. Bu, özellikle büyük veri setleri veya uzun süreli veri akışları için kullanılır. Node.js, Tarayıcılar streamler üzerinden farklı kullanımları söz konusudur.
Büyük verilerin akışları sırasında diğer işlemlerin kilitlenmemesi için Streams işlemleri asenkron olarak gerçekleşir.
1. Kavramlar
Buffer: bir veri parçasını (chunk) geçici olarak depolamak için kullanılan bir bellek alanıdır. Streams genellikle büyük veri setlerini yönetirken, her bir veri parçasını bir buffer’a yazar ve okur. Buffer, verilerin geçici olarak saklandığı ve bir sonraki işlem için beklediği yerdir.
Stream: Zaman içinde kullanıma sunulan bir dizi veridir. Ve bu dizi, eninde sonunda birleşerek bir bütün haline gelir. Bu akış
- bilgisayardan → dosyaya..
- başla bilgisayardan → bilgisayara
olabilir. Bu akış farklı farklı hızlarda internet ve bilgisayar hızınıza göre değişebilir.
Burada Stream’lerin avantajı tüm veriyi indirmeden de parça parça işleyebilme gücü, örneğin biz Film, Müzik gibi büyük media’ları stream üzerinden parça parça aktararak izleyip, dinleyebiliyoruz. Bu da biz kullanıcılara büyük avantajlar sağlıyor.
Beklemeden ilgili akan veri üzerinde çalışabilmek asenkron olmayı sağlıyor.
Stream özetle hareket eden veridir. Biz onu ister anlık, ister depolayıp kullanabiliriz.
2. Node.js Streams (Akışlar)
Node.js’de akışlar, büyük dosyaları veya veri setlerini verimli bir şekilde işlemek için yaygın olarak kullanılır. Akışlar dört türde gelir:
- Readable: Okunabilir akışlar, veri kaynağından veri okur.
- Writable: Yazılabilir akışlar, veriyi hedefe yazar.
- Duplex: Hem okunabilir hem de yazılabilir akışlardır.
- Transform: Veriyi okurken ve yazarken dönüştürür.
Reading Stream
const fs = require('fs');
const readableStream = fs.createReadStream('file.txt', {
encoding: 'utf8',
highWaterMark: 1024 // 1KB chunks
});
readableStream.on('data', chunk => {
console.log('New chunk received:', chunk);
});
readableStream.on('end', () => {
console.log('No more data.');
});
Writing Stream
const fs = require('fs');
const writableStream = fs.createWriteStream('output.txt');
writableStream.write('First chunk of data\n');
writableStream.write('Second chunk of data\n');
writableStream.end('Last chunk of data\n');
writableStream.on('finish', () => {
console.log('All data has been written.');
});
3. Fetch API Streams (Akışlar)
Tarayıcılarda Fetch API, response body bir akış olarak işleyebilir. Bu sayede büyük veri setlerini parça parça işleyebilmemize olanak sağlar.
fetch('https://jsonplaceholder.typicode.com/posts')
.then(response => {
const reader = response.body.getReader();
const decoder = new TextDecoder();
let result = '';
const processStream = ({ done, value }) => {
if (done) {
console.log('Stream complete');
console.log(result);
return;
}
result += decoder.decode(value, { stream: true });
return reader.read().then(processStream);
};
return reader.read().then(processStream);
})
.catch(error => {
console.error('Stream error:', error);
});
4. WebSocket ile Streams (Akışlar)
WebSockets, sunucu ile istemci arasında sürekli veri akışı sağlamak için kullanılır.
const socket = new WebSocket('wss://example.com/socket');
socket.onopen = () => {
console.log('Connection established');
socket.send('Hello Server!');
};
socket.onmessage = event => {
console.log('Message from server:', event.data);
};
socket.onerror = error => {
console.error('WebSocket error:', error);
};
socket.onclose = () => {
console.log('Connection closed');
};
5. Async Iterators ve Generators
Async iterators ve generators, asenkron veri akışlarını yönetmek için güçlü araçlardır.
async function* fetchData(url) {
const response = await fetch(url);
const reader = response.body.getReader();
const decoder = new TextDecoder();
while (true) {
const { done, value } = await reader.read();
if (done) break;
yield decoder.decode(value, { stream: true });
}
}
(async () => {
const url = 'https://jsonplaceholder.typicode.com/posts';
for await (const chunk of fetchData(url)) {
console.log('Received chunk:', chunk);
}
})();
6. Node.js de Stream ve Async Iterator Kullanımı
Node.js’de akışlar ve async iterators birlikte kullanılabilir.
const fs = require('fs');
async function* readFileInChunks(filePath) {
const stream = fs.createReadStream(filePath, { encoding: 'utf8', highWaterMark: 1024 });
for await (const chunk of stream) {
yield chunk;
}
}
(async () => {
for await (const chunk of readFileInChunks('largefile.txt')) {
console.log('Received chunk:', chunk);
}
})();
Okumaya Devam Et 😃
Bu yazının devamı veya yazı grubundaki diğer yazılara erişmek için bu linke tıklayabilirsiniz.