🎁 تخفیف ویژه تمامی دوره های آموزشی 🎁

آموزش Callbacks در جاوا اسکریپت

callback تابعی است که شما آن را به تابع دیگری به عنوان آرگومان برای اجرای بعد ارسال می کنید.

آموزش Callbacks در جاوا اسکریپت

callback چیست؟

در جاوا اسکریپت، توابع شهروندان درجه یک هستند. شما می توانید یک تابع را به عنوان آرگومان به تابع دیگری ارسال کنید. callback تابعی است که شما آن را به تابع دیگری به عنوان آرگومان برای اجرای بعد ارسال می کنید.

به عبارت دیگر callback تابعی است که باید پس از پایان یافتن تابعی دیگر اجرا شود. از این رو به صورت «call back» یعنی «بازگشت فراخوانی» نامگذاری شده است.

همانطور که می دانیم تابع ها در JavaScript شیء هستند. به همین دلیل تابع ها می توانند تابع های دیگری را به عنوان آرگومان بپذیرند و می توانند از سوی تابع های دیگر بازگشت یابند. تابع هایی که این کار را انجام می دهند تابع های درجه بالا (higher-order functions) نامیده می شوند. هر تابعی نیز که به صورت یک آرگومان ارسال می شود تابع callback نامیده می شود.

آموزش کال بک ها در زبان جاوا اسکریپت

callback ها از اهمیت بسیار زیادی برخوردار هستند زیرا که جاوا اسکریپت یک زبان برنامه نویسی رویداد-محور (event driven) است. بنابراین با کمک callback ها به جای این که برای ادامه برنامه منتظر بازگشت پاسخ از یک تابع باشیم، در جاوا اسکریپت همزمان با منتظر ماندن برای رویدادهای دیگر، به ادامه اجرای کدها می پردازیم. در ادامه مثال های کاربردی جهت آموزش نحوه کار و استفاده از callback ها به تفصیل نشان داده شده است

قطعه کد زیر تابع ()filter را تعریف می کند که آرایه ای از اعداد را می پذیرد و آرایه جدیدی از اعداد فرد را برمی گرداند:

callbacks in javascript

این کد چگونه کار می کند.

1- ابتدا تابع ()filter را تعریف کنید که آرایه ای از اعداد را می پذیرد و آرایه جدیدی از اعداد فرد را برمی گرداند.

2- در مرحله دوم، آرایه numbers را تعریف کنید که دارای اعداد فرد و زوج باشد.

3- در مرحله سوم، تابع ()filter را فراخوانی کنید تا اعداد فرد را از آرایه اعداد خارج کنید و نتیجه را به دست آورید.

اگر می خواهید یک آرایه حاوی اعداد زوج را برگردانید، باید تابع ()filter را تغییر دهید. برای اینکه تابع ()filter عمومی تر و قابل استفاده مجدد باشد، می توانید:

1- ابتدا منطق موجود در بلوک if را استخراج کرده و آن را در یک تابع جداگانه قرار دهید.

2- سپس، تابع را به عنوان آرگومان به تابع ()filter منتقل کنید.

کد آپدیت شده به صورت زیر است:

کال بک ها در زبان برنامه نویسی جاوا اسکریپت

نتیجه یکسان است. با این حال، می توانید هر تابعی را که یک آرگومان را می پذیرد و مقدار بولین را برمی گرداند به آرگومان دوم تابع ()filter ارسال کنید.

برای مثال، می توانید از تابع ()filter برای برگرداندن آرایه ای از اعداد زوج مانند زیر استفاده کنید:

کال بک ها در زبان برنامه نویسی جاوا اسکریپت

طبق تعریف،isOdd و isEven توابع callback یا callbacks هستند. از آنجایی که تابع ()filter یک تابع را به عنوان آرگومان می پذیرد، به آن تابع مرتبه بالا (high-order function) می گویند.

یک callback می تواند یک تابع anonymous باشد، که تابعی بدون نام مانند زیر است:

callbacks as anonymous functions

در این مثال، به جای استفاده از یک تابع مجزا، یک تابع بی نام (anonymous function) را به تابع ()filter ارسال می کنیم.

در ES6، می توانید از یک arrow function مانند زیر استفاده کنید:

callbacks in javascript

دو نوع callbacks وجود دارد: callback های همزمان و غیر همزمان (synchronous and asynchronous callbacks).

callback های همزمان (Synchronous callbacks)

یک synchronous callback در طول اجرای تابع مرتبه بالا که از callback استفاده می کند، اجرا می شود. isOdd و isEven نمونه هایی از callback های از نوع synchronous هستند زیرا در طول اجرای تابع ()filter اجرا می شوند.

callback های غیر همزمان (asynchronous callbacks)

پس از اجرای تابع مرتبه بالا که از callback استفاده می کند، یک callback از نوع asynchronous اجرا می شود.

غیر همزمانی (asynchronicity) به این معنی است که اگر جاوا اسکریپت باید منتظر باشد تا عملیاتی کامل شود، بقیه کد را در حین انتظار اجرا می کند.

توجه داشته باشید که جاوا اسکریپت یک زبان برنامه نویسی تک نخی (single-threaded) است که عملیات غیر همزمان را از طریق صف callback و event loop انجام می دهد.

فرض کنید که باید اسکریپتی ایجاد کنید که تصویری را از یک سرور راه دور دانلود کرده و پس از اتمام دانلود، آن را پردازش کند:

callback های غیر همزمان

با این حال، دانلود یک عکس از یک سرور راه دور بسته به سرعت شبکه و اندازه تصویر زمان می برد.

تابع ()download زیر از تابع ()setTimeout برای شبیه سازی درخواست شبکه استفاده می کند:

asynchronous callbacks in javascript

و این کد تابع ()process را شبیه سازی می کند:

آموزش کال بکها در زبان برنامه نویسی جاوا اسکریپت

وقتی کد زیر را اجرا می کنید:

callbacks

خروجی زیر را دریافت خواهید کرد:

آموزش کال بک ها در زبان برنامه نویسی جاوا اسکریپت

این چیزی نیست که انتظار داشتید زیرا تابع ()process قبل از تابع ()download اجرا می شود. ترتیب درست باید به صورت زیر باشد:

1- عکس را دانلود کنید و منتظر بمانید تا دانلود کامل شود.

2- تصویر را پردازش کنید

برای حل این مشکل، می توانید تابع ()process را به تابع ()download ارسال کنید و پس از اتمام دانلود، تابع ()process را در داخل تابع ()download اجرا کنید، مانند این:

callbacks in javascript

خروجی در ادامه نشان داده شده است.

asynchronous callback

در حال حاضر، این به همان شکلی که انتظار داشتیم کار می کند.

در این مثال، ()process یک callback است که به یک تابع asynchronous منتقل می شود.

هنگامی که از یک callback برای ادامه اجرای کد پس از یک عملیات asynchronous استفاده می کنید، این callback یک asynchronous callback نامیده می شود.

برای خلاصه تر کردن کد، می توانید تابع ()process را به عنوان یک تابع بی نام تعریف کنید:

کال بکهای غیر همزمان در زبان جاوا اسکریپت

کنترل خطاها

تابع ()download فرض می کند که همه چیز خوب کار می کند و هیچ استثنایی (exceptions) را در نظر نمی گیرد. کد زیر دو callbacks را معرفی می کند: succsess و failure به ترتیب برای رسیدگی به حالت های موفقیت و شکست:

کنترل خطای کال بک ها در جاوا اسکریپت

callback های تودرتو و هرم Doom

چگونه سه عکس را دانلود کرده و آنها را به صورت متوالی پردازش می کنید؟ یک روش معمولی فراخوانی تابع ()download در داخل تابع callback است، مانند این:

callback های تودرتو و هرم Doom

خروجی در ادامه نشان داده شده است.

nesting callbacks in javascript

این اسکریپت کاملاً خوب کار می کند. با این حال، زمانی که پیچیدگی به طور قابل توجهی افزایش می یابد، این استراتژی callback مقیاس خوبی ندارد.

Nesting یا تودرتوی بسیاری از توابع غیرهمزمان در داخل کال بک ها به عنوان هرم عذاب (pyramid of doom) یا جهنم کال بک (callback hell) شناخته می شود.

آموزش callbacks

برای اجتناب گرفتار شدن در هرم عذاب، از توابع promises یا async/wait استفاده کنید.

خلاصه آنچه که در این مقاله آموزشی JavaScript توضیح داده شد:

1- یک callback تابعی است که به عنوان آرگومان به تابع دیگری منتقل می شود تا بعدا اجرا شود.

2- تابع مرتبه بالا تابعی است که تابع دیگری را به عنوان آرگومان می پذیرد.

3- توابع callback می توانند همزمان یا غیرهمزمان باشند.

Callbacks Synchronous callbacks Asynchronous callbacks آموزش کال بک ها جاوا اسکریپت

مقالات این دسته بندی