مفهوم Callback در جاوا اسکریپت — به زبان ساده
ما در بلاگ فرادرس تا به این جا مجموعه مطالبی در خصوص مفاهیم جاوا اسکریپت برای افراد مبتدی جهت درک بهتر طرز کار توسعه وب منتشر کردهایم. در این نوشته نیز قصد داریم در خصوص مفهوم Callback در جاوا اسکریپت صحبت بکنیم. بدین ترتیب در طی چند دقیقه کوتاه با مثالهای ساده با این مفهوم آشنا خواهید شد.
Callback چیست؟
Callback به بیان ساده تابعی است که باید پس از پایان یافتن تابعی دیگر اجرا شود. از این رو به این صورت «call back» یعنی «بازگشت فراخوانی» نامگذاری شده است.
اگر بخواهیم کمی دقیقتر صحبت کنیم، تابعها در جاوا اسکریپت شیء هستند. به همین دلیل تابعها میتوانند تابعهای دیگری را به عنوان آرگومان بپذیرند و میتوانند از سوی تابعهای دیگر بازگشت یابند. تابعهایی که این کار را انجام میدهند به صورت «تابعهای درجه بالا» (higher-order functions) نامیده میشوند. هر تابعی نیز که به صورت یک آرگومان ارسال میشود به نام تابع callback خوانده میشود.
تا به این جا صرفاً تعاریف را مطرح کردیم، اما در ادامه تلاش میکنیم این مفهوم را با مثالهای عملی بهتر درک کنیم.
چرا به Callback نیاز داریم؟
Callback-ها به این دلیل بسیار مهم هستند که جاوا اسکریپت یک زبان برنامهنویسی رویداد-محور (event driven) است. بدین ترتیب به جای این که برای ادامه برنامه منتظر بازگشت پاسخ از یک تابع بمانیم، در جاوا اسکریپت همزمان با منتظر ماندن برای رویدادهای دیگر، به ادامه اجرای کارها میپردازیم. به مثال ابتدایی زیر توجه کنید:
1function first(){
2 console.log(1);
3}
4
5function second(){
6 console.log(2);
7}
8
9first();
10second();
همان طور که انتظار داریم تابع first ابتدا اجرا میشود و سپس تابع second پس از آن اجرا شده و موارد زیر را در کنسول ارائه میکنند:
// 1 // 2
تا به این جا همه چیز به خوبی پیش رفته است؛ اما اگر تابع first شامل نوعی کد باشد که نتواند بیدرنگ اجرا شود چطور؟ برای نمونه تصور کنید این تابع یک درخواست API ارسال میکند که برای دریافت پاسخ باید منتظر بمانیم. برای شبیهسازی این وضعیت از تابع setTimeout جاوا اسکریپت برای به تأخیر انداختن فراخوانی تابع مذکور استفاده میکنیم. به این ترتیب در اجرای تابع مورد نظر به میزان 500 میلیثانیه تأخیر میگذاریم تا وضعیت انتظار برای دریافت پاسخ از درخواست API را شبیهسازی کنیم. اینک کد ما به شکل زیر در آمده است:
1function first(){
2 // Simulate a code delay
3 setTimeout( function(){
4 console.log(1);
5 }, 500 );
6}
7
8function second(){
9 console.log(2);
10}
11
12first();
13second();
در حال حاضر نیاز نیست که با طرز کار ()setTimeout آشنا باشیم. تنها نکته مهم این است که بدانید کد ;(console.log(1 را به درون تأخیر 500 میلیثانیهای منتقل کردهایم. بنابراین اینک وقتی تابعمان را فراخوانی بکنیم چه اتفاقی میافتد؟
first(); second();
// 2 // 1
با این که ما تابع ()first را ابتدا فراخوانی کردهایم؛ اما نتیجه این تابع پس از تابع ()second در خروجی ارائه شده است. بدین ترتیب میبینیم که جاوا اسکریپت تابع first را طبق انتظار قبل از تابع second اجرا کرده است؛ اما پیش از اجرای second منتظر تمام شدن اجرای first نمانده است.
ایجاد یک Callback
اینک یک Callback را به صورت عملی ایجاد میکنیم. ابتدا با استفاده از کلیدهای Ctrl + Shift + J پنجره Chrome Developer Console را در مرورگر کروم (در فایرفاکس از میانبرهای Ctrl + Shift + k) خود باز کنید و اعلان تابع زیر را در کنسول وارد نمایید:
1function doHomework(subject) {
2 alert(`Starting my ${subject} homework.`);
3}
در کد فوق ما تابع doHomework را ساختهایم. این تابع یک متغیر میگیرد که موضوع تکلیف خانگی است. این تابع را میتوان با وارد کردن دستور زیر در کنسول فراخوانی کرد:
doHomework('math'); // Alerts: Starting my math homework.
اینک callback را به عنوان آخرین پارامتر به تابع ()doHomework ارسال میکنیم. در این زمان تابع callback در آرگومان دوم فراخوانی ما به ()doHomework تعریف شده است.
1function doHomework(subject, callback) {
2 alert(`Starting my ${subject} homework.`);
3 callback();
4}
5
6doHomework('math', function() {
7 alert('Finished my homework');
8});
همان طور که میبینید، اگر کد فوق را در کنسول خود وارد کنید، دو اعلان را به صورت پشت سر هم دریافت میکنید. بدین ترتیب ابتدا اعلان «starting homework» و سپس اعلان «finished homework» ارائه میشود.
اما همواره نیاز نیست که تابعهای callback در فراخوانی تابعهای جاوا اسکریپت تعریف شوند. آنها را میتوان در هر جای کد مانند زیر تعریف کرد:
1function doHomework(subject, callback) {
2 alert(`Starting my ${subject} homework.`);
3 callback();
4}
5
6function alertFinished(){
7 alert('Finished my homework');
8}
9
10doHomework('math', alertFinished);
نتیجه اجرای این مثال دقیقاً همانند مثال قبلی خواهد بود؛ اما تنظیمات آن کمی متفاوت است. همان طور که شاهد هستید، ما تعریف تابع alertFinished را به صورت یک آرگومان در طی فراخوانی تابع ()doHomework ارسال کردهایم.
یک مثال واقعی
برای بررسی سناریوهای دنیای واقعی در مورد callback-ها بهترین مورد، API ها هستند. زمانی که درخواستهایی به API میفرستیم، پیش از آن که بتوانیم روی پاسخ API کاری انجام بدهیم، باید منتظر دریافت آن بمانیم. در مثال زیر یک کد Callback واقعی مربوط به API توییتر را مشاهده میکنید:
1T.get('search/tweets', params, function(err, data, response) {
2 if(!err){
3 // This is where the magic will happen
4 } else {
5 console.log(err);
6 }
7})
- T.get به این معنی است که درخواستی را به توییتر ارسال میکنیم.
- سه پارامتر در این درخواست وجود دارند که ‘search/tweets’ مسیر درخواست و params پارامترهای جستجو است و یک تابع ناشناس نیز به عنوان callback ارسال میشود.
Callback در این جا اهمیت زیادی دارد، زیرا باید منتظر پاسخی از سمت سرور باشیم و سپس کد خود را ادامه بدهیم. ما نمیدانیم که درخواست API ما پس از ارسال پارامترهای جستجو از طریق درخواست مذکور، موفق خواهد بود یا نه و از این رو باید منتظر بمانیم. زمانی که توییتر پاسخی ارسال میکند، تابع callback ما فراخوانی میشود. توییتر یا یک شیء خطا (error) و یا یک شیء پاسخ (response) به ما بازمیگرداند. در تابع callback میتوانیم با استفاده از گزاره if بررسی کنیم که درخواستمان موفق بوده یا نه و سپس بر همین مبنا عمل مناسب را انجام دهیم.
اینک شما با مفهوم callback آشنا شدهاید و طرز کار آن را نیز میدانید. البته این مقاله صرفاً یک مطلب مقدماتی در مورد callback-ها محسوب میشود و موارد زیادی وجود دارند که باید بیاموزید.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی
- آموزش جاوا اسکریپت (JavaScript)
- مجموعه آموزشهای طراحی و توسعه پروژه های وب
- آموزش تعریف توابع در جاوا اسکریپت (JavaScript)
- آموزش جاوا اسکریپت — مجموعه مقالات جامع وبلاگ فرادرس
- 1۰ کتابخانه و فریمورک جاوا اسکریپت که باید آنها را بشناسید
- منطق شرطی (Conditional Logic) در جاوا اسکریپت — از صفر تا صد
==
خیلی ساده و روان توضیح دادید ممنونم
واقعا ممنون از اینه مطلب رو خیلی ساده و کاربردی توضیح دادین