کانال بله, جهت پشتیبانی و اطلاع رسانی کانال بله, جهت پشتیبانی و اطلاع رسانی
عضویت

آموزش تابع Generator در ES6

آموزش کار با تابع Generator در ES6:

تابع های مولد یا Generator Function مفهوم جدیدی است که در ES6 معرفی شده است. این مفهوم روش جدیدی برای کار با روندهای تکرار شونده (iterators) و تابع ها ارائه کرده است.
تابع Generator نوع متفاوتی از تابع ها هستند که می توانند آن ها را در میانه اجرا یک یا چندین بار متوقف کرده، خروجی بگیرید و دوباره اجرای آنها را ادامه دهید.
هنگامی که یک تابع استاندارد فراخوانی می شود، کنترل برنامه با تابع فراخوانی شده تا پایان اجرا و تولید خروجی می ماند اما تابع های Generator Function به فراخوان کننده تابع ها اجازه می دهد، اجرای آن را کنترل کرده، موقتی از آن خارج شده و دوباره به ادامه اجرا بازگردد.
شکل زیر نحوه عملکرد تابع های استاندارد و تابع های Generator Function در جاوا اسکریپت را نشان می دهد:

آموزش کار با تابع Generator در ES6

تابع Generator عملکردی مشابه تابع های معمولی دارند، به غیر از موارد تفاوت های لیست زیر:

  • وقتی که تابع Generator فراخوانی می شود، کد خود را اجرا نمی کند. به جایش یک شی ویژه به نام “Generator object” را جهت مدیریت اجرای تابع بر می گرداند.
  • تابع Generator می تواند در هر لحظه ای از اجرا، کنترل برنامه را به شی فراخوان کننده خود بازگردانده یا یک نتیجه (yield) را به وی بدهد.
  • برخلاف تابع های معمولی جاوا اسکریپت، تابع Generator Function چندین نتیجه نهایی (return) یا نتیجه در میانه اجرا (yield) را بر حسب نیاز و کد خود برگرداند.

ساختار دستوری تابع Generator بسیار شبیه تابع های استاندارد جاوا اسکریپت است. تنها فرق اساسی آنها این است که در تابع Generator کلمه کلیدی function با پسوند (*) علامت گذاری می شود. در ساختارهای کد زیر، چند روش متفاوت برای نوشتن تابع Generator را نشان داده ایم:

function* mygenfun()    // Valid  
{  
yield 1;  
yield 2;  
...  
...  
}  
  
function *mygenfun()    // Valid  
{  
yield 1;  
yield 2;  
...  
...  
}  
  
function*mygenfun() // Valid  
{  
yield 1;  
yield 2;  
...  
...  
} 
            

مثال: در کد مثال عملی زیر، یک تابع Generator به نام ()gen ایجاد کرده ایم که توسط دستور next، 3 خروجی را تولید می کند:

function* gen()  
{  
yield 100;  
yield;  
yield 200;  
}  
// Calling the Generator Function  
var mygen = gen();  
console.log(mygen.next().value);  
console.log(mygen.next().value);  
console.log(mygen.next().value);  
            

خروجی :

100
undefined
200
            

آموزش کار با دستور yield در ES6:

دستور yield می تواند اجرای تابع را به صورت موقت به حالت تعلیق درآورده و مقداری به شی فراخوان کننده تابع برگرداند. دستور yield می تواند این حالت را به اندازه کافی نگه دارد تا عملکرد تابع از جایی که متوقف شده بود، مجددا از سر گرفته شود. وقتی که دستور yield برگردد، تابع بلافاصله ادامه اجرای خود را شروع می کند. این نوع تابع ها می توانند چندین خروجی یا مجموعه از خروجی را تولید کنند.

آموزش کاربرد متد ()next در تابع Generator:

در کد مثال بالا، از متد ()next که متد اصلی در تابع Generator است، استفاده کرده ایم. وقتی متد ()next را به همراه یک آرگومان فراخوانی می کنید، اجرای تابع Generator را از نقطه ای که متوقف شده، از سر گرفته، عبارت yield expression که تابع در آنها متوقف شده بود را با آرگومان ارسالی از متد ()next، جایگزین می کند.
نتیجه متد ()next، همواره یک شی (Object) است که دو خاصیت عمده دارد:

  • مقدار value: که همان مقدار یا value دستور yield است.
  • انجام شده done: یک مقدار درست یا غلط (Boolean) است که اگر کد تابع تمام شده باشد، مقدار true و در غیر اینصورت مقدار false را بر می گرداند.

مثال: در کد مثال عملی زیر یک تابع Generator به نام ()show ایجاد کرده ایم و متد ()next را روی آن به کار برده ایم:

function* show() {  
yield 100;  
}  
  
var gen = show();   //here 'gen' is a generator object  
console.log(gen.next()); // { value: 100, done: false }  
            

خروجی :

{ value: 100, done: false }
            

آموزش شی تابع مولد Generator Object:

تابع Generator Function شی Generator Object بر می گرداند. یک شی Generator Object نمونه ای از تابع Generator بوده و با هر دو رابط تکرار شونده (iterable ) و تکرار کننده (iterator) مطابقت دارد.
شی Generator Object را هم می توانید با فراخوانی متد ()next و هم با استفاده از یک حلقه (loop) به کار ببرید. شی Generator Object یک ساختار تکرار کننده (iterator) است. به همین دلیل می توانید آن را در ساختارهای حلقه مثل for … of و سایر تابع هایی که اشیای تکرار شونده قبول می کنند، به کار ببرید.
در کد مثال عملی فوق، در متد ()next، متغیر gen یک شی Generator است.

آموزش کاربرد دستور Return در Generator:

از دستور return برای بازگردادن یک مقدار (value) به فراخوان کننده و مجری تابع استفاده می شود. از این دستور برای خاتمه دادن به روند اجرای تابع و بازگرداندن نتیجه حاصل از آن (value) به صدا زننده تابع استفاده می گردد. درون تابع های جاوا اسکریپت، کدهایی که بعد از دستور return نوشته شوند، اجرا نمی شوند. به همین دلیل است که دستور return بایستی آخرین خط کدهای یک تابع در جاوا اسکریپت باشد.
مثال: در کد مثال عملی زیر، کاربرد دستور return را نشان داده ایم:

function* myGen()  {  
yield 'First yield statement';  
yield 'Second yield statement';  
return 'Return statement';  
yield 'Second yield statement';  
}  
let genobj = myGen();  
  
console.log(genobj.next());    //returns {value: 'First yield statement', done: false}  
  
console.log(genobj.next());   //returns {value: 'Second yield statement', done: false}  
  
console.log(genobj.next());  //returns {value: 'Return statement', done: true}  
  
console.log(genobj.next()); //returns {value: undefined, done: true}  
            

در مثال فوق، یک تابع Generator function به نام ()myGen حاوی 4 دستور که 3 دستور آن yield statement بوده و یک دستور return است را تعریف کرده ایم. هر زمان که دستور متد ()next فراخوانی می شود، اجری تابع تا رسیدن به دستور بعدی yield از سر گرفته می شود.
می توانید در خروجی مشاهده کنید که چطور متد اول ()next عبارت ‘First yield Statement’ را برگردانده است. وقتی که متد دوم ()next را صدا می کنیم، روند اجرای تابع از سر گرفته شده و عبارت ‘Second yield Statement’ را به خروجی ارسال می کند. با صدا زدن متد سوم ()next، تابع هیچ دستور yield دیگری پیدا نکرده و توسط دستور return عبارت ‘Return Statement’ را بر می گرداند. اما وقتی برای چهارمین بار متد ()next فراخوانی می شود، نمی تواند دستور yield در خط آخر را اجرا نمایید، زیرا بعد از دستور return نوشته شده است. در کد فوق مشاهده می کنید که متد ()next نمی تواند دستوری بعد از دستور return را اجرا کرده و وضعیت تابع را خاتمه یافته ‘done: true’ اعلام می کند.

{ value: 'First yield statement', done: false }
{ value: 'Second yield statement', done: false }
{ value: 'Return statement', done: true }
{ value: undefined, done: true }
            

آموزش کاربرد Generator در حلقه for … of:

استفاده از حلقه for … of همراه با تابع Generator Function حجم کدنویسی دستورات را کاهش می دهد. در کد مثال عملی زیر، یک تابع Generator به نام ()vowels تعریف کرده و سپس آن را در یک حلقه for … of به کار برده ایم:

"use strict"   
function* vowels() {   
   // here the asterisk marks this as a generator   
   yield 'A';   
   yield 'E';   
   yield 'I';   
   yield 'O';   
   yield 'U';   
}   
for(let alpha of vowels()) {   
   console.log(alpha);   
}  
            

خروجی :

A
E
I
O
U
            
نکته مهم:

تابع Generator Function را نمی توان به صورت تابع های Arrow Function به کار برد.

1400/06/12 1786 0
نظرات شما

نظرات خود را ثبت کنید...