اگرچه ساخت ایتریتورهای سفارشی و دستی یک ابزار بسیار کاربردی است، اما پیادهسازی آنها نیاز به برنامهنویسی و مراقبت خیلی دقیقی دارد؛ چون مجبور هستید وضعیت داخلی (Internal State) آنها را به صورت صریح و دستی مدیریت و ردیابی کنید.
در این میان، توابع ژنراتور (Generator functions) یک جایگزین فوقالعاده قدرتمند را در اختیارتان میگذارند: آنها به شما اجازه میدهند یک الگوریتم تکرارپذیر را فقط با نوشتن یک تابع واحد تعریف کنید؛ تابعی که اجرای آن پیوسته و مداوم نیست و میتواند در طول کار متوقف شود! توابع ژنراتور با استفاده از ساختارِ علامت ستاره یعنی function* نوشته میشوند.
وقتی یک تابع ژنراتور صدا زده میشود، کدهای داخل آن در ابتدا اصلاً اجرا نمیشوند! در عوض، این تابع یک نوعِ خاص از ایتریتورها را برمیگرداند که به آن ژنراتور (Generator) میگویند. هر زمان که با صدا زدن متد next()ِ ژنراتور، یک مقدار مصرف میشود، تابع ژنراتور شروع به اجرا میکند و این اجرا تا زمانی ادامه مییابد که تابع به کلمه کلیدی yield برخورد کند.
شما میتوانید این تابع را هر چند بار که دلتان خواست صدا بزنید و هر بار یک ژنراتورِ جدید دریافت کنید. اما یادتان باشد که هر ژنراتورِ ساختهشده را فقط یکبار میتوان پیمایش و مصرف کرد.
حالا میتوانیم همان مثال قبلیِ بازه (Range Iterator) را با این روش جدید بازنویسی کنیم. رفتار این کد دقیقاً و موبهمو مشابه مثال قبلی است، اما نوشتن و خواندن این پیادهسازی به شدت راحتتر و سادهتر است:
function* makeRangeIterator(start = 0, end = Infinity, step = 1) {
let iterationCount = 0;
for (let i = start; i < end; i += step) {
iterationCount++;
yield i; // مقدار i را برمیگرداند و اجرای تابع را همینجا متوقف میکند
}
return iterationCount; // مقدار نهایی در پایان کار
}
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: https://developer.mozilla.org/en-US/docs/Web/JavaScript