ژنراتورها مقادیر تولیدی خود را دقیقاً در همان لحظهای که درخواست میشود (On demand) محاسبه میکنند. این ویژگی به آنها اجازه میدهد تا توالیهایی که محاسبهشان سنگین و هزینهبر است (یا حتی توالیهای بینهایت، همانطور که بالاتر دیدیم) را به شکلی کاملاً بهینه و کارآمد نشان دهند.
نکته پیشرفته اینجاست که متد next() میتواند یک مقدار ورودی (آرگومان) هم بپذیرد! شما میتوانید از این مقدار برای تغییر دادن وضعیت داخلی خودِ ژنراتور استفاده کنید. هر مقداری که به متد next() پاس داده شود، توسط عبارت yield در داخل تابع دریافت میشود.
⚠️ یک نکته بسیار حیاتی: مقداری که در اولین مرتبهی فراخوانیِ متد
next()پاس داده میشود، همیشه توسط موتور جاوااسکریپت نادیده گرفته میشود.
بیا با هم یک مثال جذاب ببینیم. در کد زیر، یک ژنراتور اعداد فیبوناچی ساخته شده است که با پاس دادن مقدار به متد next(x)، میتوان توالی اعداد را ریستارت (شروع مجدد) کرد:
function* fibonacci() {
let current = 0;
let next = 1;
while (true) {
// مقدار پاس داده شده به next() در متغیر reset ذخیره میشود
const reset = yield current;
[current, next] = [next, next + current];
if (reset) {
current = 0;
next = 1;
}
}
}
const sequence = fibonacci();
console.log(sequence.next().value); // 0
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
console.log(sequence.next().value); // 3
console.log(sequence.next().value); // 5
console.log(sequence.next().value); // 8
console.log(sequence.next(true).value); // 0 <- ارسال ترو باعث ریست شدن توالی میشود
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 1
console.log(sequence.next().value); // 2
throw() در ژنراتورهاشما میتوانید با صدا زدن متد throw() روی یک ژنراتور و پاس دادن یک مقدار استثنا به آن، ژنراتور را مجبور کنید که خطایی را پرتاب کند. این استثنا دقیقاً از همان نقطهای که ژنراتور در آن متوقف (Suspend) شده است پرتاب میشود؛ انگار که عبارت yieldِ متوقفشده در آن لحظه، یک دستور throw بوده است.
اگر این خطای پرتابشده از داخل خودِ بدنه ژنراتور (مثلاً با try/catch) گرفته و مدیریت نشود، خطا در پشته فراخوانی به سمت بالا حرکت کرده و از طریق همان متد throw() به بیرون سرایت میکند. در این حالت، اگر بعد از آن دوباره متد next() را صدا بزنید، ویژگی done آن مقدار true را برمیگرداند (یعنی ژنراتور کاملاً بسته میشود).
return() در ژنراتورهاژنراتورها متد دیگری به نام return() دارند. کار این متد این است که مقدار دادهشده را به عنوان مقدار نهایی برمیگرداند و کارِ خودِ ژنراتور را در همان لحظه برای همیشه تمام میکند (باعث اتمام ژنراتور میشود).
این محتوا کاملا رایگان توسط تیم کدلپر ترجمه شده و در اختیار شما کاربران عزیز قرار گرفته است، هر گونه کپی برداری برای مقاصد غیر رایگان و بدون ذکر منبع، مورد پیگیری قانونی قرار میگیرد.
ترجمه شده از منبع: https://developer.mozilla.org/en-US/docs/Web/JavaScript