دوال المولدات في JavaScript
في هذه المقالة، سنشرح دوال المولدات في JavaScript۔
YouTube Video
دوال المولدات في JavaScript
دوال المولدات في JavaScript هي دوال خاصة تختلف عن الدوال العادية في أنها تستطيع تنفيذ تنفيذ كسول والتوقف والاستئناف۔ من خلال فهم دوال المولدات، يمكنك التعامل بكفاءة مع العمليات غير المتزامنة ومعالجة البيانات الكبيرة بشكل تسلسلي۔ هنا، سنقدم شرحاً تفصيلياً لكيفية عمل دوال المولدات، وكيفية استخدامها، وأمثلة عملية۔
ما هي دوال المولدات؟
يتم تعريف دالة المولد باستخدام function*
(تعريف الدالة مع علامة النجمة) وعلى عكس الدوال العادية، يمكنها التوقف عن التنفيذ مؤقتاً واستئنافه مع الحفاظ على حالتها۔ تتيح دوال المولدات "التنفيذ الكسول" وتعيد النتائج تدريجياً، مما يتيح إدارة فعالة للذاكرة ومعالجة تسلسلية۔
الصياغة
1function* generatorFunction() {
2 yield 'First value';
3 yield 'Second value';
4 return 'Done';
5}
بهذه الطريقة، يمكن لدالة المولد أن تحتوي على تعبيرات yield
متعددة واستخدام yield
للتوقف عن التنفيذ مؤقتاً۔ عند استدعاء دالة المولد، لا يتم تنفيذ جسم الدالة فوراً، ويتم إرجاع كائن المولد۔ يمكنك استدعاء طريقة next()
على هذا الكائن لاستئناف الدالة من النقطة التي توقفت عندها۔
الاستخدام الأساسي لدوال المولدات
بعد ذلك، دعونا نلقي نظرة على مثال أساسي لاستخدام دوال المولدات۔
1function* simpleGenerator() {
2 yield 1;
3 yield 2;
4 yield 3;
5}
6
7const gen = simpleGenerator();
8
9console.log(gen.next()); // { value: 1, done: false }
10console.log(gen.next()); // { value: 2, done: false }
11console.log(gen.next()); // { value: 3, done: false }
12console.log(gen.next()); // { value: undefined, done: true }
نقطة مهمة يجب ملاحظتها هنا هي أن المولد يعيد القيم في كل مرة باستخدام yield
، وطالما أن خاصية done
هي false
، فهذا يشير إلى وجود قيم أخرى قادمة۔ الاتصال الأخير بـnext()
يعيد done: true
، مما يشير إلى أن المولد قد انتهى۔
الكلمة المفتاحية yield
وإيقاف القيم مؤقتاً
yield
هي كلمة مفتاحية تشير إلى نقطة توقف مؤقتة داخل دالة المولد۔ القيمة الموجودة على يمين yield
يتم إرجاعها عند استدعاء next()
۔ بالإضافة إلى ذلك، يسمح yield
بالتواصل الثنائي الاتجاه۔ بعبارة أخرى، عند تمرير قيمة كمعامل إلى طريقة next()
، يتم إرسال هذه القيمة إلى دالة المولد۔
1function* generatorWithYield() {
2 const value1 = yield 'First yield';
3 console.log('Received value:', value1);
4 const value2 = yield 'Second yield';
5 console.log('Received value:', value2);
6}
7
8const gen = generatorWithYield();
9
10console.log(gen.next()); // { value: 'First yield', done: false }
11console.log(gen.next('Apple')); // Received value: Apple
12 // { value: 'Second yield', done: false }
13console.log(gen.next('Banana'));// Received value: Banana
14 // { value: undefined, done: true }
في هذا المثال، يستدعي next('Apple')
القيمة 'Apple'
ويرسلها إلى دالة المولد حيث يتم استخدامها داخل الدالة۔
إدارة حالة المولد
يمكن للمولدات الاحتفاظ بحالتها أثناء التنفيذ، مما يتيح تمثيلاً مختصراً للحلقات الطويلة أو المعالجة التسلسلية۔ المثال التالي يوضح منشئاً يقوم بإنتاج الأرقام بلا حدود۔
1function* infiniteGenerator() {
2 let i = 0;
3 while (true) {
4 yield i++;
5 if (i > 10) {
6 break;
7 }
8 }
9}
10
11const gen = infiniteGenerator();
12
13console.log(gen.next().value); // 0
14console.log(gen.next().value); // 1
15console.log(gen.next().value); // 2
16// Continues...
هذا المنشئ يقوم بإنتاج الأرقام باستمرار باستخدام حلقة while(true)
، مما يسمح لك بالحصول على القيم حسب الحاجة۔ هذا يُمكّن من معالجة مجموعات البيانات الكبيرة بكفاءة۔
تطبيقات دوال المنشئ
دوال المنشئ مناسبة لتنفيذ عمليات متعددة بالتتابع۔ على سبيل المثال، تكون مفيدة في معالجة طلبات واجهات البرمجة التطبيقية (API) بالتتابع أو تقسيم ومعالجة الملفات الكبيرة۔
1function* apiRequestGenerator() {
2 yield fetch('https://codesparklab.com/json/example1.json');
3 yield fetch('https://codesparklab.com/json/example2.json');
4 yield fetch('https://codesparklab.com/json/example3.json');
5}
لذلك، فإن المنشئات، التي يمكن استخدامها في المعالجة غير المتزامنة، مفيدة للغاية في معالجة البيانات بالتتابع بكفاءة۔
المنشئات غير المتزامنة
المنشئات غير المتزامنة التي تم تقديمها في ES2018 تتيح لك إرجاع القيم غير المتزامنة بالتتابع عن طريق دمج async
و yield
۔ هذا يجعل من الممكن كتابة معالجة غير متزامنة بشكل مختصر بالاقتران مع await
۔
الصياغة
1async function* asyncGenerator() {
2 yield await Promise.resolve(1);
3 yield await Promise.resolve(2);
4 yield await Promise.resolve(3);
5}
6
7const gen = asyncGenerator();
8
9(async () => {
10 for await (const value of gen) {
11 console.log(value); // 1, 2, 3
12 }
13})();
يمكن للمنشئات غير المتزامنة استرداد القيم بالتتابع باستخدام حلقة for await...of
۔ هذا النمط مفيد بشكل خاص عند التعامل مع تدفقات البيانات غير المتزامنة۔
مثال عملي: تبسيط المعالجة غير المتزامنة باستخدام المنشئات
تُستخدم دوال المنشئ أيضًا لتبسيط تدفق المعالجة غير المتزامنة۔ على سبيل المثال، عن طريق دمج yield
و Promise
كما هو موضح أدناه، يمكنك كتابة العمليات غير المتزامنة لتبدو متزامنة۔
1function* asyncFlow() {
2 const data1 = yield fetch('https://codesparklab.com/json/example1.json');
3 console.log(data1);
4 const data2 = yield fetch('https://codesparklab.com/json/example2.json');
5 console.log(data2);
6}
7
8const gen = asyncFlow();
9
10function handleAsync(generator) {
11 const next = (promise) => {
12 promise.then((result) => {
13 const { value, done } = generator.next(result);
14 if (!done) {
15 next(value);
16 }
17 });
18 };
19
20 next(generator.next().value);
21}
22
23handleAsync(gen);
هذا الكود يقوم بمعالجة طلبات واجهات البرمجة التطبيقية (API) بالتتابع باستخدام منشئ ومعالجة النتائج۔
الملخص
دوال المنشئ هي واحدة من ميزات JavaScript القوية، حيث تملك القدرة على إيقاف واستئناف تنفيذ وظيفة معينة۔ هذا يسمح بمعالجة متتابعة، ومعالجة غير متزامنة، ومعالجة فعالة لمجموعات البيانات الكبيرة۔ فهم المنشئات هو خطوة مهمة لإتقان التقنيات المتقدمة في JavaScript۔
يمكنك متابعة المقالة أعلاه باستخدام Visual Studio Code على قناتنا على YouTube.۔ يرجى التحقق من القناة على YouTube أيضًا.۔