المولدات هي نمط coroutine (coroutine) من جافا سكريبت. إنه يشير إلى الوظائف التي يمكن إيقافها ثم استئنافها أثناء التنفيذ. ويرافق الوظيفة برموز النجمة في الوظيفة ، مثل الوظيفة*، وبعض الكلمات الرئيسية المميزة في الوظيفة ، مثل العائد والعائد*.
الدالة* generatorfn () {console.log ('look ma i تم تعليقها')} var generator = generatorfn () // [1] setTimeOut (function () {generator.next () // [2]} ، 2000)يتم شرح [1] و [2] في الكود على النحو التالي:
1. هذا مولد يبدأ مع توقف مؤقت. لا يوجد إخراج وحدة التحكم في هذا الوقت.
2. فقط عن طريق الاتصال بأسلوبها التالي () ، يمكن تنفيذ المولد وتشغيله حتى يواجه الكلمة الرئيسية أو العائد التالي. الآن لدينا إخراج وحدة التحكم.
دعونا نلقي نظرة على حالة أخرى:
وظيفة *generator () {console.log ('start!') ؛ var i = 0 ؛ بينما (صواب) {if (i <3) synd i ++ ؛ }} var gen = generator () ؛يشبه الرمز أعلاه الكود الأول ، ولكن هناك كلمة رئيسية عائد إضافية في وظيفة المولد. عندما يتم استدعاء الرمز أعلاه ، لن يتم تنفيذها على الفور ، ولكن سيؤدي إلى إيقاف حالة الاستعداد ، لذلك لن يكون هناك إخراج بدء. لا يتم تنفيذها حتى مكالمة NEXT ().
var ret = gen.next () ؛ // start! console.log (ret) ؛ // {value: 0 ، int: false}و RET أعلاه هي نتيجة المولد. لها خصوانيان:
■ القيمة ، قيمة العائد في وظيفة المولد ،
■ القيام به ، هذا هو العلم الذي يشير إلى ما إذا كانت وظيفة المولد تعود.
تابع الرمز على النحو التالي:
console.log (gen.next ()) ؛ // {value: 1 ، done: false} console.log (gen.next ()) ؛ // {value: 2 ، done: false} console.log (gen.next ()) ؛ليس لدى المولد أي لغز في البرمجة المتزامنة ، وهو مناسب بشكل خاص للبرمجة غير المتزامنة.
المولد له خصائصان:
1. يمكنك اختيار القفز من وظيفة ما ، دع الرمز الخارجي يقرر وقت العودة إلى هذه الوظيفة ومواصلة التنفيذ.
2. قادرة على أداء التحكم غير المتزامن.
انظر إلى رمز التنفيذ غير المتزامن التالي:
var gen = generator () ؛ console.log (gen.next (). value) ؛ setTimeout (function () {console.log (gen.next ()الإخراج هو:
0
الخطوة 2
1
الخطوة الأولى
بمعنى آخر ، لن تنتظر أن تنتهي المهلة في SetTimeout ، ولكنها ستستمر مباشرة مع "الخطوة الثانية" ولن يتم حظرها في Settimeout.
دعونا نلقي نظرة على قطعة أخرى من الكود:
دالة* channel () {var name = griven 'hello ، ما هو اسمك؟' // [1] return 'well hi' name} var gen = channel () console.log (gen.next (). value) // hello ، ما هو اسمك؟ [2] Console.log (Gen.Next ('Billy')) // well hi here billy [3]يمكنك أيضًا استخدام * أثناء اجتياز:
الدالة* iter () {for (var i = 0 ؛ i <10 ؛ i ++) العائد i} لـ (var val of iter ()) {console.log (val) // outputs 1؟ -؟ 9}سوء فهم مشترك
بما أنني أستطيع إيقاف تنفيذ الوظيفة ، هل يجب أن أسمح لهم بالتنفيذ بالتوازي؟ لا ، لأن JavaScript هو موضوع واحد ، وإذا كنت ترغب في طلب تحسينات الأداء ، فإن المولد ليس طبقك.
على سبيل المثال ، ينفذ الرمز التالي أرقام فيبوناتشي بشكل منفصل:
الدالة fib (n) {var current = 0 ، next = 1 ، swap for (var i = 0 ؛ i <n ؛ i ++) {swap = current ، current = next next = swap+next} return current}}نتائج الأداء هي كما يلي: (كلما كان ذلك أفضل)
نتائج:
منتظم 1263899
مولد 37541
المولدات تألق
يمكن للمولدات تبسيط تعقيد الوظائف في JavaScript.
مهمة كسول
على الرغم من أنه يمكن تنفيذ المهمة البطيئة باستخدام عمليات إغلاق JS ، إلا أن استخدام العائد سيبسيط بشكل كبير. من خلال الإيقاف المؤقت والانتعاش ، يمكننا الحصول على قيم رقمية عندما نحتاج إليها. على سبيل المثال ، يمكن أن تسحب وظيفة Fibgen أعلاه قيمًا جديدة عندما نحتاج إليها:
var fibiter = fibgen (20) var next = fibiter.next () console.log (next.value) setTimeOut (function () {var next =تسلسل لانهائي
نظرًا لأنك قد تكون كسولًا لتعيين القيم ، يمكنك إجراء بعض الحيل Haskell ، على غرار التسلسلات اللانهائية. هنا يمكنك أن تسفر عن عدد تسلسل لا حصر له.
الدالة* fibgen () {var current = 0 ، next = 1 ، swap بينما (true) {swap = current ، current = next next = swap + next rivel current}}دعونا نلقي نظرة على المهمة البطيئة لتيار فيبوناتشي واطلب منه إعادة رقم فيبوناتشي الأول بعد 5000:
لـ (var num of fibgen ()) {if (num> 5000) break} console.log (num) // 6765التحكم غير المتزامن للعملية
باستخدام المولدات لتنفيذ التحكم غير المتزامن للعملية ، فإن أكثر حزم مكتبة وعد مختلفة شيوعًا ، فكيف تعمل؟
في عالم العقدة ، يرتبط كل شيء بالتراجع ، وهي وظيفتنا غير المتزامنة منخفضة المستوى. يمكننا استخدام المولدات لإنشاء قناة اتصال ، وذلك لكتابة الكود غير المتزامن بأسلوب البرمجة المتزامنة.
Run (function* () {console.log ("start") var file = rendfile ("./ async.js") // [1] console.log (file.toString ())})الملاحظة 1 تعني أن البرنامج سيستمر قبل انتظار Async.JS لإرجاع النتيجة.
Genify هو إطار عمل يجلب المولدات إلى بيئة برمجة طبيعية ، باستخدام ما يلي:
NPM تثبيت genify للتثبيت ، الرمز كما يلي:
var q = required ('q') ؛ var fs = require ('fs') ؛ var genify = require ('genify') ؛ // لف كائنك في genify functionvar object = genify ({concatfiles: function * (file1 ، file2 ، outfile) {file1 = griven q.nfcall (fs.readfile ، file1) ؛ file2 = griven q.nfcall (fs.readfile ، file2) concated ؛ // concatfiles هي وظيفة مولد تستخدم القدرات القوية للمولدات. Object.concatfiles ('./ somefile1.txt' ، './somefile2.txt' ، './concated.txt'mmnmelrealmny).التفسير التفصيلي أعلاه لاستخدام مولدات JavaScript في Node.js هو كل المحتوى الذي أشاركه معك. آمل أن تتمكن من إعطائك مرجعًا وآمل أن تتمكن من دعم wulin.com أكثر.