آموزش رایگان جاوا اسکریپت (JavaScript)

Async/Await: نوشتن کدهای خواناتر و ناهم‌زمان در جاوا اسکریپت - آموزش کامل با مثال‌ها

1403/07/30 20:50 محراب حسن زاده
Async/Await: نوشتن کدهای خواناتر و ناهم‌زمان در جاوا اسکریپت - آموزش کامل با مثال‌ها

در جاوا اسکریپت، مدیریت عملیات‌های ناهم‌زمان به روش‌های مختلفی امکان‌پذیر است. یکی از مدرن‌ترین و خواناترین روش‌ها برای این کار، استفاده از async و await است. این امکانات به شما این امکان را می‌دهند که کدهای ناهم‌زمان را به شکلی مشابه کدهای هم‌زمان بنویسید و از پیچیدگی‌های استفاده از Promiseها جلوگیری کنید. در این مقاله، به بررسی مفاهیم async و await، نحوه استفاده از آن‌ها و نکات مهم پیرامون آن‌ها خواهیم پرداخت.

 

مقدمه‌ای بر async و await

مفهوم async

کلیدواژه async برای تبدیل یک تابع به تابعی ناهم‌زمان (asynchronous) استفاده می‌شود. یک تابع async همیشه یک Promise را بازمی‌گرداند. حتی اگر شما از return یک مقدار ساده استفاده کنید، آن مقدار به صورت خودکار در یک Promise محصور می‌شود.

ساختار کلی تابع async:


async function myAsyncFunction() {
  return "Hello, World!";
}

 

توضیح:

در این مثال، تابع myAsyncFunction به دلیل استفاده از کلیدواژه async، یک Promise را بازمی‌گرداند که مقدار "Hello, World!" را به عنوان نتیجه خود دارد.

 

مفهوم await

کلیدواژه await برای منتظر ماندن تا زمان تکمیل یک Promise و دریافت نتیجه آن استفاده می‌شود. await فقط درون توابع async قابل استفاده است.

ساختار کلی await:


async function myAsyncFunction() {
  const result = await somePromise;
  console.log(result);
}

 

توضیح:

در این مثال، await منتظر می‌ماند تا Promise somePromise به وضعیت Fulfilled برسد و نتیجه آن را در متغیر result ذخیره می‌کند.

 

نوشتن کد با استفاده از async و await

استفاده از async/await برای عملیات‌های ناهم‌زمان

مثال:


function fetchData() {
  return new Promise((resolve) => {
    setTimeout(() => resolve("Data fetched"), 2000);
  });
}

async function getData() {
  const result = await fetchData();
  console.log(result); // Output: Data fetched
}

getData();

 

در این مثال:

  • تابع fetchData یک Promise را برمی‌گرداند که پس از 2 ثانیه با پیام "Data fetched" حل می‌شود.

  • تابع getData با استفاده از await منتظر می‌ماند تا Promise fetchData تکمیل شود و سپس نتیجه را در کنسول چاپ می‌کند.

 

مدیریت خطاها با async/await

برای مدیریت خطاها در توابع async, از بلوک‌های try/catch استفاده می‌کنید.

مثال:


function fetchData(shouldFail) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (shouldFail) {
        reject("Failed to fetch data");
      } else {
        resolve("Data fetched");
      }
    }, 2000);
  });
}

async function getData() {
  try {
    const result = await fetchData(true);
    console.log(result);
  } catch (error) {
    console.error(error); // Output: Failed to fetch data
  }
}

getData();

 

در این مثال:

  • اگر fetchData با خطا مواجه شود، Promise آن به وضعیت Rejected می‌رود.

  • بلوک catch در تابع getData این خطا را مدیریت کرده و در کنسول چاپ می‌کند.

 

مزایای استفاده از async/await

خوانایی بیشتر

استفاده از async/await باعث می‌شود که کدهای ناهم‌زمان به شکل مشابه کدهای هم‌زمان به نظر برسند و در نتیجه، خوانایی و نگهداری آن‌ها آسان‌تر شود.

مثال:


async function processData() {
  const data = await fetchData();
  const processedData = await process(data);
  console.log(processedData);
}

 

در این مثال، استفاده از async/await باعث شده که مراحل مختلف پردازش داده‌ها به شکل خطی و واضح نمایش داده شوند.

 

جلوگیری از Callback Hell

async/await به جلوگیری از "Callback Hell" (یا مشکلات تو در توی Callbacks) کمک می‌کند که به ویژه زمانی که توابع ناهم‌زمان به طور مداوم فراخوانی می‌شوند، اهمیت دارد.

مثال با Callback Hell:


fetchData(function (data) {
  process(data, function (processedData) {
    save(processedData, function (result) {
      console.log(result);
    });
  });
});

 

مثال با async/await:


async function processData() {
  const data = await fetchData();
  const processedData = await process(data);
  const result = await save(processedData);
  console.log(result);
}

 

استفاده از Promise.all و Promise.allSettled با async/await

Promise.all

برای اجرای چندین Promise به طور هم‌زمان و دریافت نتایج آن‌ها، می‌توانید از Promise.all استفاده کنید.

مثال:


async function getAllData() {
  try {
    const [data1, data2] = await Promise.all([fetchData(), fetchData()]);
    console.log(data1, data2);
  } catch (error) {
    console.error(error);
  }
}

 

در این مثال، Promise.all به شما این امکان را می‌دهد که منتظر بمانید تا هر دو Promise به نتیجه برسند و سپس نتایج آن‌ها را در کنسول چاپ کنید.

 

Promise.allSettled

برای دریافت نتایج تمام Promiseها، حتی اگر برخی از آن‌ها به وضعیت Rejected رفته باشند، از Promise.allSettled استفاده کنید.

مثال:


async function getAllSettledData() {
  const results = await Promise.allSettled([fetchData(true), fetchData()]);
  results.forEach(result => {
    if (result.status === 'fulfilled') {
      console.log('Success:', result.value);
    } else {
      console.error('Error:', result.reason);
    }
  });
}

 

در این مثال، Promise.allSettled نتایج تمام Promiseها را به شما می‌دهد و می‌توانید وضعیت هر Promise را بررسی کرده و نتیجه را در کنسول چاپ کنید.

 

نکات و توصیه‌ها

استفاده از await درون try/catch

همیشه بهتر است از await درون بلوک‌های try/catch استفاده کنید تا خطاهای احتمالی را به درستی مدیریت کنید و از مشکلات اجرایی جلوگیری کنید.

 

جلوگیری از بلاک کردن Thread اصلی

توجه داشته باشید که استفاده از await درون توابع async باعث بلاک شدن Thread اصلی نمی‌شود، بلکه اجرای توابع ناهم‌زمان را به صورت مؤثر مدیریت می‌کند.

 

استفاده از Promise.all برای بهینه‌سازی

برای بهینه‌سازی زمان‌بندی و اجرای موازی عملیات‌ها، از Promise.all استفاده کنید تا چندین Promise را به طور هم‌زمان اجرا کنید و نتایج آن‌ها را مدیریت کنید.

 

نتیجه‌گیری

async و await ابزارهای قدرتمندی هستند که به شما این امکان را می‌دهند تا کدهای ناهم‌زمان را به شکلی خواناتر و مشابه کدهای هم‌زمان بنویسید. با استفاده از این امکانات، می‌توانید به سادگی با عملیات‌های ناهم‌زمان، مدیریت خطاها و اجرای موازی توابع تعامل کنید. این روش‌ها به شما کمک می‌کنند تا کدهای پیچیده‌تر و کارآمدتری بنویسید و مشکلات مربوط به خوانایی و نگهداری کد را کاهش دهید.

پرسش و پاسخ

نظری یافت نشد

مطالب مشابه

آموزش ایجاد تگ‌های صفحه‌بندی در HTML و CSS: طراحی و استایل‌دهی pagination
1402/05/29 21:27

آموزش ایجاد تگ‌های صفحه‌بندی در HTML و CSS: طراحی و استایل‌دهی pagination

مطالعه بیشتر
آموزش کامل متغیرهای $_GET، $_POST و $_REQUEST در PHP به زبان ساده
1405/05/01 20:01

آموزش کامل متغیرهای $_GET، $_POST و $_REQUEST در PHP به زبان ساده

مطالعه بیشتر
استفاده از clip-path در CSS برای برش‌های زیبا و جذاب: راهنمای کامل
1403/08/16 22:58

استفاده از clip-path در CSS برای برش‌های زیبا و جذاب: راهنمای کامل

مطالعه بیشتر
راهنمای جامع قوانین نام‌گذاری متغیرها در PHP بر اساس استاندارد گوگل
1405/03/24 00:57

راهنمای جامع قوانین نام‌گذاری متغیرها در PHP بر اساس استاندارد گوگل

مطالعه بیشتر
تفاوت include، require، include_once و require_once در PHP
1405/05/01 20:32

تفاوت include، require، include_once و require_once در PHP

مطالعه بیشتر
آموزش جامع خواندن و نوشتن فایل متنی در PHP (به زبان ساده)
1405/05/04 23:17

آموزش جامع خواندن و نوشتن فایل متنی در PHP (به زبان ساده)

مطالعه بیشتر
آموزش کامل Super Global ها در PHP (متغیرهای سراسری)
1405/05/01 19:58

آموزش کامل Super Global ها در PHP (متغیرهای سراسری)

مطالعه بیشتر
آموزش استایل‌دهی لینک‌ها در CSS: طراحی و تنظیمات ساده برای لینک‌های HTML
1402/06/07 00:01

آموزش استایل‌دهی لینک‌ها در CSS: طراحی و تنظیمات ساده برای لینک‌های HTML

مطالعه بیشتر
آموزش کامل دستور switch-case در PHP (به همراه مثال‌های کاربردی)
1405/04/04 00:08

آموزش کامل دستور switch-case در PHP (به همراه مثال‌های کاربردی)

مطالعه بیشتر
آموزش CSS Blend Modes: ادغام رنگ‌ها و تصاویر برای طراحی وب جذاب
1403/08/09 20:29

آموزش CSS Blend Modes: ادغام رنگ‌ها و تصاویر برای طراحی وب جذاب

مطالعه بیشتر
مدیریت فرم‌ها و ورودی‌ها در Vue.js | آموزش Form Handling با مثال کاربردی
1404/09/22 00:40

مدیریت فرم‌ها و ورودی‌ها در Vue.js | آموزش Form Handling با مثال کاربردی

مطالعه بیشتر
آموزش ایجاد، دسترسی و اصلاح آرایه‌ها در جاوا اسکریپت: راهنمای کامل
1403/07/04 17:11

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

مطالعه بیشتر

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