You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
1. ما مانند حالت عادی `fetch` انجام میدهیم، اما به جای `response.json()`، یک stream reader میگیریم: `response.body.getReader()`.
90
90
91
-
توجه کنید که نمیتوان همزمان از هر دو روش برای خواندن یک پاسخ استفاده کرد: یا باید از reader استفاده کنیم یا از متدهای آمادهی response.
92
-
91
+
توجه کنید که نمیتوان همزمان از هر دو روش برای خواندن یک پاسخ استفاده کرد: یا باید از reader استفاده کنیم یا از متدهای آمادهی response.
93
92
2. قبل از خواندن، میتوانیم از هدر `Content-Length` طول کل پاسخ را به دست آوریم.
94
93
95
94
این مقدار ممکن است در درخواستهای cross-origin وجود نداشته باشد (به فصل <info:fetch-crossorigin> مراجعه کنید) و در عمل هم سرور مجبور به ارسال آن نیست. اما معمولاً وجود دارد.
96
-
97
95
3. تابع `await reader.read()` را تا زمانی که تمام شود اجرا میکنیم.
98
96
99
97
ما تکههای پاسخ را در آرایهی `chunks` جمع میکنیم. این مهم است چون بعد از مصرف شدن پاسخ، دیگر نمیتوان آن را دوباره با `response.json()` یا روشهای مشابه خواند (اگر امتحان کنید خطا خواهید گرفت).
100
-
101
98
4. در پایان، ما `chunks` را داریم -- آرایهای از قطعات بایت `Uint8Array`. باید آنها را به یک خروجی واحد تبدیل کنیم. متأسفانه متد مستقیمی برای اتصال آنها وجود ندارد، بنابراین این کار را دستی انجام میدهیم:
102
-
103
99
1. یک `Uint8Array` جدید با طول کل ایجاد میکنیم: `chunksAll = new Uint8Array(receivedLength)`
104
100
2. سپس با `.set(chunk, position)` هر قطعه را پشت سر هم داخل آن کپی میکنیم.
105
-
106
101
5. در نهایت دادهی نهایی در `chunksAll` قرار دارد، اما هنوز رشته نیست.
107
102
108
103
برای تبدیل به رشته، باید این بایتها را تفسیر کنیم. کلاس داخلی [TextDecoder](info:text-decoder) دقیقاً همین کار را انجام میدهد. سپس در صورت نیاز میتوانیم آن را با `JSON.parse` تبدیل کنیم.
109
104
110
-
اگر به جای رشته دادهی باینری بخواهیم، کار سادهتر است: کافی است مراحل 4 و 5 را با یک خط جایگزین کنیم:
111
-
105
+
اگر به جای رشته دادهی باینری بخواهیم، کار سادهتر است: کافی است مراحل 4 و 5 را با یک خط جایگزین کنیم:
دوباره توجه کنید: این روش برای *پیشرفت آپلود* نیست (فعلاً با `fetch` ممکن نیست)، فقط برای *پیشرفت دانلود* است.
119
113
120
-
همچنین اگر اندازهی داده مشخص نباشد، باید در حلقه مقدار `receivedLength` را بررسی کنیم و اگر از یک حدی بیشتر شد، حلقه را متوقف کنیم تا آرایهی `chunks` باعث مصرف بیش از حد حافظه نشود.
114
+
همچنین اگر اندازهی داده مشخص نباشد، باید در حلقه مقدار `receivedLength` را بررسی کنیم و اگر از یک حدی بیشتر شد، حلقه را متوقف کنیم تا آرایهی `chunks` باعث مصرف بیش از حد حافظه نشود.
0 commit comments