Express.js / المتقدم: عقود الموارد والكتابة والإصدار / الدرس 14
التدفق والضغط العكسي وإلغاء العميل
قيد العمل المخزن وامتلك تنظيف التدفق بعد التوصيل الجزئي أو الانقطاع أو فشل المصدر.
في هذه الصفحة
أهداف الدرس
- اشرح لماذا لا يحد التدفق الذاكرة أو يضمن التوصيل تلقائياً.
- افصل إكمال الرد وإغلاق الاتصال وتمرير الإلغاء.
يقدم التدفق حد الالتزام بالرد
يرسل التدفق البيانات تدريجياً بدلاً من بناء تصدير كامل قبل الإرسال. قد يقلل ذروة الذاكرة إذا احترمت كل مرحلة الضغط، لكن الترويسات والبايتات الأولى قد تلتزم قبل نجاح المصدر كله. لا يتحول خطأ لاحق إلى JSON بديلة نظيفة بحالة جديدة. اختر تمثيلاً يكشف القطع أو عقد إكمال مستقل عندما تحتاج الحالة إليه. لا تعتبر أول جزء أو حدث finish في الخادم إثباتاً أن المستخدم استقبل وثيقة العمل كاملة وحللها وقبلها. تتطلب صحة الملف النهائي دليلاً أو تحققاً يناسب المستهلك، لا مجرد بدء النقل.
استخدم سلسلة تدفق مراجعة وافهم أثرها على HTTP
تنسق pipeline في Node تمرير التدفق وتنظيف الخطأ، لكن توصيلها برد HTTP قد يدمر الاتصال عند الفشل. راجع السلوك قبل افتراض أن catch تستطيع إرسال رد آخر. يوضح الجزء نقل مصدر إلى رد ويترك إنشاء المصدر والتفويض خارجه عمداً، ولا ينفذ هنا. يجب ربط الإلغاء بالمصدر الفعلي وانقطاع العميل عبر واجهات يدعمها Node والموائم المختاران. لا توقف إشارة محلية برنامج تشغيل قاعدة يتجاهلها. ينبغي أن توضح الخدمة هل ينتج الانقطاع إلغاءً حقيقياً أو يستمر العمل محدوداً حتى ينتهي.
async function streamExport(source,res,pipeline) {
res.setHeader("Content-Type","text/csv; charset=utf-8");
await pipeline(source,res);
}
pipeline والمصدر محقونان غير منفذين. قد يكون الفشل أغلق الاتصال، فلا يقدم الجزء وصفة لإرسال JSON داخل catch.
احترم إشارة الكتابة وقيد المصدر الأعلى
عندما تعيد write القيمة false تطلب من المنتج التوقف حتى تتاح سعة، غالباً عبر drain. مواصلة صف كل النتائج تهزم الضغط العكسي وتنمي الذاكرة رغم استعمال تدفق. قيد أيضاً نافذة الجلب ومخازن التحويل وحجم العنصر؛ فقد يتجاوز سجل واحد ضخم الميزانية. يعد highWaterMark في نمط الكائنات كائنات لا بايتات، فلا يمثل سقف بايتات عاماً. اشتق الحدود من عقد البيانات وافحص كل المراحل لا الرد النهائي فقط. انخفاض حجم مخزن آخر السلسلة لا يصلح مصدراً يجلب المجموعة كاملة مسبقاً.
نمذج سقفاً محلياً لقبول الأجزاء المعلقة
يسمح الحساب بجزء معلق عندما يناسب عدد بايتاته الميزانية المتبقية، ويرفض الضخم حتى إن كان الصف فارغاً. القيم تعليمية؛ فلا ينفذ الشرط ضغط Node أو يقيس ذاكرة العملية. تحمل المخازن كلفة إضافية وقد تخزن عدة مراحل في الوقت نفسه. يوضح النموذج شرطاً مفيداً: لا يكفي عدد الأجزاء إذا تفاوتت أحجامها. اختبر السلوك والإلغاء والتنظيف في دمج معزول مأذون قبل ادعاء تشغيل. وتحقق من أن رفض الجزء لا يترك المصدر ينتج بلا مستهلك أو يستهلك الموارد إلى أجل غير محدد.
function fits(pendingBytes,nextBytes,limit) {
return nextBytes >= 0 && pendingBytes + nextBytes <= limit;
}
console.assert(fits(4,6,10));
console.assert(!fits(4,7,10));
console.assert(!fits(0,11,10));
تقبل الميزانية 4+6 وترفض 4+7 وعنصراً من 11 بايتاً. هو حساب لا قياس ذاكرة.
امتلك الإكمال والانقطاع مرة واحدة
قد ينتهي الرد طبيعياً أو يغلق مبكراً أو يفشل أثناء المصدر. ميز النتائج في رصد محدود واجعل التنظيف متحملاً للتكرار حتى لا تحرر إشارات متعددة المورد خطأ. أزل المستمع وحرر المؤشر أو مقبض الملف وفق مسؤولية الموائم. ولتصدير قابل للاستئناف حدد نطاق المؤشر والاحتفاظ والإكمال المعتمد بدلاً من البدء العمياني بعد جزئي. يشغل المقرر حساب البايتات فقط، ولا يجرب خادم تدفق أو نقلاً أو مؤشراً أو قطع شبكة. يوضح ذلك أن صحة حساب محدود ليست دليلاً على توصيل كامل.
الأخطاء الشائعة وإصلاحها
تنمو الذاكرة أثناء التدفق
- لماذا يحدث؟
- تجاهلت مرحلة الضغط أو خزنت المجموعة كلها.
- كيف تصلحه؟
- قيد نوافذ المصدر والعناصر وكل مخزن تحويل.
- كيف تتجنب تكراره؟
- افحص المراحل بعينات ممثلة معزولة.
تحاول catch إرسال JSON بعد تدمير الاتصال
- لماذا يحدث؟
- عومل فشل السلسلة كخطأ قبل الالتزام.
- كيف تصلحه؟
- اتبع سلوك فشل السلسلة وHTTP الموثق.
- كيف تتجنب تكراره؟
- اختبر الفشل قبل البايتات وبعدها منفصلين.
يستمر المصدر بعد مغادرة العميل
- لماذا يحدث؟
- لم يصل الانقطاع إلى إلغاء المصدر.
- كيف تصلحه؟
- مرر الإلغاء المدعوم وحرر الموارد المملوكة.
- كيف تتجنب تكراره؟
- تحقق من توقف المصدر لا رفض المستدعي فقط.
اختبر فهمك
1. لماذا ليس حد عدد الكائنات حد بايتات؟
اعرض الحل المشروح
تختلف أحجام الكائنات ويعد النمط المداخل. قد يحمل مدخل سلسلة أو ثنائياً ضخماً. قيد الحجم وراع المخازن المتزامنة والكلفة. يحدد الحساب السياسة ولا يقيس بصمة كائنات JavaScript أو سلسلة عاملة.
2. هل يعيد العميل تصديراً جزئياً دون تصميم إضافي؟
اعرض الحل المشروح
قد تكرر الإعادة صفوفاً أو تخلط نسخ المصدر. حدد لقطة ثابتة أو مؤشراً محفوظاً بنطاق وكيف يعرف العميل الاكتمال. لا تخلق إعادة HTTP الضمانات ولا تثبت أن النقل السابق خلا من بايتات مفيدة.
أهم ما تعلمته
- يحتاج التدفق ضغطاً عبر المراحل وسياسة فشل متأخر صريحة.
- الإكمال والانقطاع وإلغاء المصدر حقائق منفصلة.