توابع بازگشتی

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

احتمالا تابحال نام کال بک فانکشن را شنیده اید. شاید به درستی مفهوم این نوع از توابع را متوجه نشده باشید. در ادامه سعی می کنم با ذکر مثال و توضیحات تکمیلی کمک به درک کامل از این نوع توابع داشته باشید. توصیه می شود کدهایی که در حین این آموزش آورده شده است را خودتان در برنامه کد ادیتور (code editor) خود وارد و اجرا کنید تا طور کامل در جریان روند کار باشید.

توجه: من معمولا نام ها را به شکل همان نام انگلیسی خودشون استفاده می کنم. این کار باعث می شود که شما با نام های اصلی آشنا شوید که در آینده اگر مقاله ای خوانندید که به زبان انگلیسی بود برایتان غریب نباشد. مثلا همین موضوع. کال بک فانکشن در فارسی توابع بازگشتی ترجمه شده است.

تعریف کال بک فانکشن

کال بک یک تابع است که به عنوان یک پارامتر در یک تابع دیگر قرار می گیرد و در آن تابع اجرا می شود. به این می گوییم کال بک فانکشن. در خیلی از زمان ها ما از این توابع استفاده می کنیم. به عنوان مثال وقتی از forEach استفاده می کنیم در واقع یک کال بک فانکشن است یا مثلا در زمان استفاده از متد setTimeout.

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

تعریف متغیر

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



  const posts = [{
    title: 'post one',
    body: 'this is post one'
  },
  {
    title: 'post two',
    body: 'this is post two'
  }
];

تابع برای ایجاد پست

تابعی با نام createPost ایجاد می کنیم. کار این تابع این است که با استفاده از دستور push یک آیتم جدید به انتهای آرایه اضافه می کند. در این تابع از متد setTimeout استفاده کرده ایم. روش کار این متد به این شکل است که یک پارامتر می گیرد (خود این پارامتر از نوع کال بک فانکشن است) که بعد از مدت زمان معینی که توسط برنامه نویس تعیین می شود آن را اجرا می کند. این زمان بر اساس میلی ثانیه است.


function createPost(post) {
  setTimeout(function () {
    posts.push(post);
  }, ۲۰۰۰);
}
  

تابع برای نمایش پست ها

یک تابع با نام getPosts ایجاد می کنیم. کار این تابع این است که پست هایی که  توسط تابع قبلی (createPost) ایجاد کرده ایم را نمایش دهد. در این تابع با استفاده از forEach حلقه ای ایجاد می کنیم که پست ها را نمایش دهد. روش کار متد forEach به این شکل است که یک پارامتر می گیرد (خود این پارامتر از نوع کال بک فانشکن است) که توسط آن مقدار هر المنت در یک آرایه را نمایش می دهد. در آخر forEach را درون یک setTimeout قرار می دهیم که بعد از مدت زمان مشخصی که تعیین می کنیم اجرا شود.

  
  function getPosts() {
  setTimeout(function () {
    let output = '';
    posts.forEach(function (post) {
      output += `
  • ${post.title}
  • `; }); document.body.innerHTML = output; }, ۱۰۰۰); }

    اضافه کردن مقدار جدید به posts

    با استفاده از تابع createPost که قبلا ایجاد کرده ایم یک آبجکت جدید به آرایه posts اضافه می کنیم.

    
      createPost({
      title: 'post three',
      body: 'this is post three'
    });
      

    نمایش پست ها

    اکنون با استفاده از تابع getPosts که قبلا ایجاد کرده ایم پست ها را نمایش می دهیم. تابع را اجرا کنید، در کمال تعجب خواهید دید که فقط دو آبجکت اول آن ایجاد کرده ایم نمایش داده می شود اما آبجکت سوم که با استفاده از تابع createPost بعدا به آن اضافه کردیم درخروجی نمایش داده نمی شود. مشکل کجاست؟ به تابع ایجاد پست نگاه کنید، در اینجا بعد از زمان ۲ ثانیه یک پست جدید ساخته می شود حالا به تابع getPosts نگاه کنید، در اینجا بعد از یک ثانیه پست ها نمایش داده می شوند. این به چه معناست؟ یعنی ابتدا پست ها نمایش داده می شوند (یک ثانیه) سپس پست جدید ساخته می شود. در این حالت هیچگاه پست جدید نمایش داده نمی شود چون قبل از اینکه ایجاد شود پست ها نمایش داده شده اند. راه حل برطرف کردن این مشکل استفاده از کال بک فانکشن است. به تابع createPost کال بک فانکشن اضافه می کنیم تا این مشکل را برطرف کنیم.

     

    کل دستورات قبل از ایجاد کال بک فانکشن

      
    
    const posts = [{
        title: 'post one',
        body: 'this is post one'
      },
      {
        title: 'post two',
        body: 'this is post two'
      }
    ];
    
    /* تابع اضافه کردن */
    function createPost(post) {
      setTimeout(function () {
        posts.push(post);
      }, ۲۰۰۰);
    }
    
    /* تابع نمایش */
    function getPosts() {
      setTimeout(function () {
        let output = '';
        posts.forEach(function (post) {
          output += `
  • ${post.title}
  • `; }); document.body.innerHTML = output; }, ۱۰۰۰); } /* استفاده از تابع جهت اضافه کردن پست */ createPost({ title: 'post three', body: 'this is post three' }); /* نمایش پست ها */ getPosts();

    اضافه کردن callback

    خوب کاری که باید انجام شود این است که به تابع createPost یک پارامتر جدید اضافه می کنیم. (این پارامتر جدید همان کال بک فانکشن است)  و سپس بعد از دستور push آن را صدا می زنیم. من در اینجا اسم این پارامتر را callback گذاشتم اما هر اسمی که شما بگذارید قابل قبول است بعضی ها اسم پارامتر های کال بک را cb می گذارند.

    
    
    function createPost(post,callback) {
      setTimeout(function () {
        posts.push(post);
        callback();
      }, ۲۰۰۰);
    }
      

    اکنون که کال بک را اضافه کردیم برای ایجاد پست جدید که با استفاده از همین تابع انجام می دادیم باید کمی تغییرات ایجاد کنیم. همانطور که در کد زیر ملاحظه می کنید بعد از آبجکت نام تابع getPosts را به عنوان پارامتر به تابع اضافه می کنیم. اتفاقی که در اینجا می افتد این است که قبل از اینکه کار تابع در مدت زمان ۲ ثانیه که مشخص کردیم به پایان برسد، تابع getPosts که به عنوان کال بک فراخوانی و اجرا می شود و سپس به انتهای تابع می رسد.

    
    
    createPost({
      title: 'post three',
      body: 'this is post three'
    }, getPosts);
    
      

    کد کامل برنامه همراه با پرارامتر کال بک

      
    
    const posts = [{
        title: 'post one',
        body: 'this is post one'
      },
      {
        title: 'post two',
        body: 'this is post two'
      }
    ];
    
    /* تابع اضافه کردن */
    function createPost(post,callback) {
      setTimeout(function () {
        posts.push(post);
        callback();
      }, ۲۰۰۰);
    }
    
    /* تابع نمایش */
    function getPosts() {
      setTimeout(function () {
        let output = '';
        posts.forEach(function (post) {
          output += `
  • ${post.title}
  • `; }); document.body.innerHTML = output; }, ۱۰۰۰); } /* استفاده از تابع جهت اضافه کردن پست */ createPost({ title: 'post three', body: 'this is post three' }, getPosts);

    امیدوارم که مفهوم کال بک فانکشن رو به خوبی متوجه شده باشید. برای درک بهتر چندین بار کدها را نوشته و آن را مرور کنید.

    نویسنده: سعید پناهی

    طراح و توسعه دهنده وب، رابط کاربری. فرانت اند. علاقه مند به یادگیری و آموزش

    دیدگاهتان را بنویسید

    نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

    احتمالا از اینها هم خوشتون بیاد

    تفاوت let و var

    در گذشته تنها روشی که برای تعریف متغیر در جاوا اسکریپت استفاده می شد استفاده از کلمه کلیدی var بود. این کلمه برای مدت های طولانی برای تعریف متغیر ها در جاوا اسکریپت به کار می رفت اما مشکلاتی هم به همراه داشت که باعث شد درنسخه های بعدی جاوا اسکریپت با اضافه کردن دو کلمه کلیدی دیگر const و let برای تعریف کردن متغیر، این مشکلات بر طرف شود. بعد از انتشار نسخه ۶ جاوا اسکریپ دو کلمه کلیدی دیگر let و const برای تعریف متغیر به این زبان اضافه شد. که در مجموع سه کلمه کلیدی برای تعریف متغیر در این زبان مورد استفاده قرار می گیرد. به طور کلی کلمه کلیدی const برای تعریف یک ثابت به کار می رود. منظور از ثابت متغیری است که مقدار آن ثابت است مثلا اگر یک ثابت رو معادل یک رشته قرار دادیم نمی توان آن را تغیر داد.

    لزوم استفاده از Lazy Loading برای تصاویر

    امروزه استفاده از تصاویر در محتوای صفحات وب بسیار زیاده شده. اصلا بدون استفاده از تصاویر، صفحات وب خشک و کسل کننده می شوند. این موضوع وقتی اهمیت بیشتری پیدا می کند که محتوای وب سایت، مطلب آموزشی یا تبلیغ و مواردی از این دست داشته باشد. که در این حالت نقش تصاویر بسیار مهم هستند و بدون استفاده از تصاویر عملا کار ناقص می ماند. اما مشکل اینجاست که استفاده از تصاویر باعث می شود که سرعت لود صفحه ی وب پایین بیاد و همین موضوع به خودی خود یک مساله جدی است. اگر کاربری وارد وب سایت شود و سرعت لود صفحه مناسب نباشد باعث می شود کاربر به جای اینکه صبر کند تا صفحه لود شود به طور کامل از وب سایت شما خارج شود. حالا فرض کنید که سرعت اینترنت کاربر هم زیاد مناسب نباشد! برای حل این مشکل از تکنیک Lazy Loading استفاده می کنیم که درادامه به بررسی بیشتر و نحوه استفاده از آن می پردازیم.

    strict-mode

    Strict Mode در جاوا اسکریپت

    وقتی از ‘use strict’ در ابتدای کدهای خود در جاوا اسکریپت استفاده کنید، یعنی به جاوا اسکریپت گفته اید که به کدهایی که می نوسید سخت گیرانه تر نگاه کند. مثلا اگر یک متغیر را تعریف نکرده باشید و بخواهید از آن استفاده کنید با پیغام خطا مواجه می شوید این در صورتی است که اگر از strict mode استفاده نکرده باشید پیغام خطایی دریافت نمی کنید. همچنین ارورهایی که به شما نمایش داده می شود بهتر و مشخص تر مشکل را بیان کرده است. از این رو وقتی از stirct mode استفاه می کنید مجبورید که کدهای تر و تمیز تری بنوسید و این یعنی بالا رفتن کارایی برنامه تون.