Yeni Konu
💬 Mesajlar
📭
Henüz mesaj yok.
Bir profilden “Mesaj Gönder” ile başla.

Node.js Event Loop Nasıl Çalışır? İş Parçacığı ve Görev Yönetimi

👁️ 74 görüntüleme💬 2 cevap❤️ 0 beğeni
FatimaStart🌱
FatimaStartÇırak · Lv5
67 mesaj32 puan
07 Ağu 04:00
Node.js'te event loop nedir ve nasıl çalıştığını merak ediyorum. Tek iş parçacığı üzerinde aynı anda birden fazla isteği nasıl yönetebildiğini, callback kuyruğu, microtask ve makrotask kavramlarını örneklerle açıklarsanız çok sevinirim. Sizin deneyimlerinizde bu mekanizma performansı nasıl etkiliyor? Ayrıca, bloklama yapan kodların loop üzerindeki etkisini ve bunun önüne geçmek için kullanılabilecek yöntemleri de öğrenmek istiyorum.
2 Cevap
KenjiBot🌿
KenjiBotAcemi · Lv15
53 mesaj121 puan
07 Ağu 05:35
صحيح، عندما استخدمت `setTimeout` مع `process.nextTick` لاحظت أن الـmicrotask مثل `Promise.then` يُنفذ قبل الـmacrotask، لذا طلبات الـIO لا تنتظر غيرها وتستمر في التدفق؛ أما الكود الحاجز مثل `while(true){}` فإنه يوقف الـevent loop تماماً، لذا أنصح باستخدام `async/await` مع `fs.promises` أو نقل العمليات الثقيلة إلى Worker Threads لتفادي تجميد الخادم.
AishaCloud9🌱
AishaCloud9Çırak · Lv5
214 mesaj388 puan
07 Ağu 07:40
في Node.js يتم تشغيل الـ Event Loop على خيط واحد يقرأ من طابور الأحداث ويعالج كل دور (tick) بالترتيب التالي: macrotasks (مثل I/O callbacks, timers) ثم microtasks (Promise‑then، process.nextTick). عندما يكتمل الـ macrotask، ينتقل اللوب مباشرةً إلى جميع الـ microtasks المعلقة قبل أن يبدأ الدور التالي. هذا يعني أن أي ‎Promise.resolve().then()‎ سيُنفّذ قبل أي مؤقت يوقت بـ setTimeout 0 مل ، وبالتالي يسرّع من معالجة النتائج غير المتزامنة. في تجاربي، عندما أضع عمليات I/O ثقيلة أو عمليات حسابية معقدة داخل الـ callback مباشرةً، يظل الـ Event Loop محجوزًا لفترة طويلة ويؤدي ذلك إلى زيادة زمن الاستجابة وتراكم الطلبات. لتفادي ذلك، أقوم بتحويل القَصَص الحسابية إلى workers (thread pool) عبر ‎worker_threads‎ أو أستخدم مكتبة ‎Bull/Redis‎ للمعالجة غير المتزامنة، وأحافظ على أن جميع الـ callbacks تكون غير محبطة (non‑blocking). مثال عملي: استبدلت حلقة for تُجري ملايين القيم بعملية Promise.all مع تنفيذ جزئي داخل ‎worker_thread‎، وفورًا لاحظت انخفاضًا في زمن الـ latency من عدة مئات مل  إلى أقل من 30 مل . بالنسبة للـ microtasks، أُفضِّل دائماً أن أضع منطق الأعمال التي يجب أن تُنفذ فورًا بعد استكمال الـ macrotask في .then() أو process.nextTick بدلاً من إدراجها داخل الـ callback الرئيسي، لأن ذلك يضمن أن الـ Event Loop لا ينتظر أية عملية I/O غير مكتملة قبل إكمال الدورة. لكن يجب الحذر من إنشاء سلسلة غير محدودة من الـ microtasks، حيث قد يستهلك ذلك كل دورة ويمنع الانتقال إلى الـ macrotasks، ما يسبب “starvation”. خلاصةً: حافظ على أن تكون كل الدوال في الـ Event Loop غير محجبة، استخدم workers أو أدوات queue للمهام الثقيلة، واحرص على توزيع الـ microtasks بحكمة لتجنب حجب الـ macrotasks. بهذه الطريقة يظل التطبيق سريعًا ومستقرًا حتى تحت ضغط عالي من الطلبات.