プログラミング

データダウンロードの進行状況追跡

データのダウンロード進行状況の追跡と中断:JavaScriptにおける完全ガイド

データのダウンロードを行う際、特に大きなファイルを扱う場合、進行状況を追跡することは非常に重要です。進行状況を監視し、ユーザーにフィードバックを提供することで、より良いユーザーエクスペリエンスを実現できます。この記事では、JavaScriptを使用してデータのダウンロード進行状況を追跡する方法と、それを中断する方法について詳しく説明します。

1. Fetch APIによるデータのダウンロード

まず、データのダウンロードを行うための基本的な方法として、fetch()を使用します。fetch()は、HTTPリクエストを非同期で行うための関数で、Promiseベースで動作します。データをダウンロードする際、fetch()は通常、レスポンスのストリームを返します。これを利用して進行状況を追跡できます。

基本的な使用方法

javascript
fetch('https://example.com/largefile') .then(response => { // レスポンスが正常でない場合はエラーを投げる if (!response.ok) { throw new Error('Network response was not ok'); } return response.body.getReader(); }) .then(reader => { // データの読み込みを開始 const stream = new ReadableStream({ start(controller) { // データをバイト単位で読み込み function push() { reader.read().then(({ done, value }) => { if (done) { controller.close(); return; } controller.enqueue(value); push(); }); } push(); } }); return new Response(stream); }) .then(response => { // ダウンロード完了後の処理 console.log('Download complete!'); }) .catch(error => { console.error('Error during fetch:', error); });

このコードは、基本的にデータをダウンロードし、読み込んだバイトデータをストリームとして処理します。進行状況の追跡は、ReadableStreamの実装をカスタマイズすることで可能です。

2. 進行状況の追跡

進行状況を追跡するためには、fetch()で取得したレスポンスのbodyReadableStreamで読み込んでいきます。ReadableStreamでは、ストリームをバイト単位で読み込むことができますが、その際に、どれだけのデータを処理したかを追跡する方法があります。

進行状況の追跡方法

以下のコードでは、ダウンロードの進行状況を追跡し、ユーザーにフィードバックを提供する方法を示します。

javascript
fetch('https://example.com/largefile') .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } const totalBytes = parseInt(response.headers.get('Content-Length'), 10); // ダウンロードするファイルのサイズ let loadedBytes = 0; // 読み込んだデータのバイト数 const reader = response.body.getReader(); const stream = new ReadableStream({ start(controller) { function push() { reader.read().then(({ done, value }) => { if (done) { controller.close(); return; } loadedBytes += value.length; const progress = (loadedBytes / totalBytes) * 100; // 進行状況の計算 console.log(`Download progress: ${Math.round(progress)}%`); controller.enqueue(value); push(); }); } push(); } }); return new Response(stream); }) .then(response => { console.log('Download complete!'); }) .catch(error => { console.error('Error during fetch:', error); });

このコードでは、ファイルの全体サイズ(Content-Lengthヘッダー)を取得し、ダウンロード進行状況を計算しています。loadedBytesは、読み込んだデータの合計バイト数を追跡し、進行状況をパーセンテージで表示します。

3. 進行状況を表示するUIの作成

進行状況を計算できたら、次はそれをUIで表示する方法です。たとえば、プログレスバーを表示して、ユーザーにダウンロードの進行状況を視覚的に知らせることができます。

プログレスバーの作成

HTMLに以下のようなプログレスバーを追加します。

html
<progress id="progressBar" value="0" max="100">progress>

そして、JavaScriptでプログレスバーを更新するコードを追加します。

javascript
fetch('https://example.com/largefile') .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } const totalBytes = parseInt(response.headers.get('Content-Length'), 10); let loadedBytes = 0; const reader = response.body.getReader(); const progressBar = document.getElementById('progressBar'); const stream = new ReadableStream({ start(controller) { function push() { reader.read().then(({ done, value }) => { if (done) { controller.close(); return; } loadedBytes += value.length; const progress = (loadedBytes / totalBytes) * 100; progressBar.value = progress; // プログレスバーの値を更新 controller.enqueue(value); push(); }); } push(); } }); return new Response(stream); }) .then(response => { console.log('Download complete!'); }) .catch(error => { console.error('Error during fetch:', error); });

このコードでは、ダウンロードの進行状況に合わせてプログレスバーの値を更新しています。progressBar.valueに進行状況を反映させることで、ユーザーがダウンロードの進行状況をリアルタイムで確認できるようになります。

4. ダウンロードの中断

ダウンロード中に進行状況を追跡しながら、中断することも可能です。AbortControllerを使用すると、fetch()リクエストを中断することができます。

中断する方法

javascript
const controller = new AbortController(); const signal = controller.signal; fetch('https://example.com/largefile', { signal }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } const totalBytes = parseInt(response.headers.get('Content-Length'), 10); let loadedBytes = 0; const reader = response.body.getReader(); const stream = new ReadableStream({ start(controller) { function push() { reader.read().then(({ done, value }) => { if (done) { controller.close(); return; } loadedBytes += value.length; const progress = (loadedBytes / totalBytes) * 100; console.log(`Download progress: ${Math.round(progress)}%`); controller.enqueue(value); push(); }).catch(error => { console.error('Reading error:', error); controller.error(error); }); } push(); } }); return new Response(stream); }) .catch(error => { if (error.name === 'AbortError') { console.log('Download aborted'); } else { console.error('Download failed:', error); } }); // 中断操作を呼び出す例 setTimeout(() => controller.abort(), 5000); // 5秒後に中断

このコードでは、AbortControllerを使用して、指定した時間後にダウンロードを中断する処理を示しています。controller.abort()を呼び出すことで、ダウンロードが途中で停止します。

まとめ

JavaScriptでデータのダウンロード進行状況を追跡する方法と、それを中断する方法について詳しく説明しました。fetch()ReadableStreamを使って進行状況を計算し、プログレスバーを更新することができ、AbortControllerを利用してダウンロードを中断することも可能です。これらの技術を組み合わせることで、ユーザーに対してより良い体験を提供することができます。

Back to top button