۲۹ شهریور ۱۴۰۳

Techboy

اخبار و اطلاعات روز تکنولوژی

نحوه استفاده از async و await در جاوا اسکریپت

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

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

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

جاوا اسکریپت ناهمگام و در انتظار تعریف شد

برای شروع، بیایید یک تعریف کاربردی از کلیدواژه های جاوا اسکریپت async و انتظار دریافت کنیم:

  • async: تابعی را به عنوان تابعی اعلام می‌کند که حاوی کلمه کلیدی wait در آن است.
  • انتظار: یک تابع ناهمزمان را مصرف می کند که یک قول را با نحو همزمان برمی گرداند.

مصرف یک وعده جاوا اسکریپت

احتمالاً رایج‌ترین مورد استفاده در همه جاوا اسکریپت برای async و await استفاده از fetch API داخلی مرورگر است. فهرست ۱ یک تابع async را اعلام می کند و از wait در آن استفاده می کند. هدف این است که برخی از داده‌های JSON را از API عمومی Star Wars استخراج کنیم.


async function getStarWarsData() {
  try {
    const response = await fetch('https://swapi.dev/api/people/1/');
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error(error);
  }
}

getStarWarsData();
// Returns: {name: 'Luke Skywalker', height: '172', mass: '77', hair_color: 'blond', skin_color: 'fair', …}

توجه داشته باشید که می‌توانید با روشی مانند fetch()، وعده بازگشتی را بدست آورید. در این مورد، شی پاسخ. response.json() نیز یک روش ناهمزمان است که یک وعده را برمی گرداند، بنابراین ما دوباره از await استفاده می کنیم.

عملکرد getStarWarsData() ما باید با کلمه کلیدی async پیشوند شود — در غیر این صورت، مرورگر اجازه نمی دهد انتظار در بدنه خود داشته باشد.< /p>

بازسازی با async و انتظار

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


let getUserProfile = (userId) => {
  return axios.get(`/user/${userId}`)
    .then((response) => {
      return response.data;
    })
    .catch((error) => {
      // Do something smarter with `error` here
      throw new Error(`Could not fetch user profile.`);
    });
};
getUserProfile(1)
  .then((profile) => {
    console.log('We got a profile', profile);
  })
  .catch((error) => {
    console.error('We got an error', error)
  });

فهرست ۲ تابعی را تعریف می کند که یک شناسه کاربری را می گیرد و یک وعده را برمی گرداند (نوع بازگشتی axios.get().then().catch()). برای دریافت اطلاعات نمایه یک نقطه پایانی HTTP را فراخوانی می کند و با نمایه حل می شود یا با یک خطا رد می شود. این به خوبی کار می کند، اما فراوانی نحو در داخل getUserProfile منطق کسب و کار ما را به هم می زند، همانطور که در فهرست ۳ نشان داده شده است.


  .then((response) => {
     /* important stuff */
  })
  .catch((error) => {
     /* more important stuff */
  });

اکنون، بیایید ببینیم برای ساده‌سازی این برنامه چه کاری می‌توانیم انجام دهیم.

رابط‌های کاربری متقابل پلتفرم با .NET MAUI «زنده می‌شوند».

گام به گام با async/await

توابع async و await به شما امکان می‌دهند بدون تمام قول‌های نحوی سپس و catch با وعده‌ها کار کنید. معمولا نیاز دارند. در اصل، آنها کد ناهمزمان شما را قابل خواندن می کنند. کلیدواژه‌های async و wait به شما امکان می‌دهند کدی بنویسید که به صورت ناهمزمان رفتار می‌کند اما همزمان خوانده می‌شود. هر زمان که مفسر جاوا اسکریپت یک انتظار را ببیند، اجرا را متوقف می‌کند، کار را انجام می‌دهد و سپس مانند یک تماس عادی برمی‌گردد. این باعث می شود کدی خوانا و تمیز باشد، اما توانایی هماهنگ کردن همزمانی پیچیده را محدود می کند. در این موارد، شما نیاز دارید مستقیم‌تر به وعده‌هایی دسترسی داشته باشید که زیربنای async/انتظار و شروع و حل وظایف هستند.

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


let someFunction = async () => {
  let fulfilledValue = await myPromise();
};

اگر وعده با خطا رد شود، اپراتور await خطا را انجام می دهد.

GitLab 14.6 در استقرارهای توزیع شده می درخشد

بیایید تابع getUserProfile را گام به گام با استفاده از async و await بازنویسی کنیم.

افزودن کلمه کلیدی async یک تابع را ناهمزمان می کند. این به ما امکان می دهد از عملگر await در بدنه تابع استفاده کنیم:


let getUserProfile = async (userId) => {
  /* business logic will go here */
};

بعد، از کلمه کلیدی wait در وعده خود استفاده می کنیم و مقدار حل شده را به آن اختصاص می دهیم:


let getUserProfile = async (userId) => {
  let response = await axios.get(`/user/${userId}`);
  /* more to do down here */
}

ما می خواهیم ویژگی داده مقدار پاسخ حل شده خود را برگردانیم. به جای اینکه آن را در یک بلوک then قرار دهیم، می‌توانیم به سادگی مقدار را برگردانیم:


let getUserProfile = async (userId) => {
  let response = await axios.get(`/user/${userId}`);
  return response.data;
  /* more to do down here */
}

اگر HTTP ما ناموفق باشد و وعده رد شود، اپراتور wait پیام رد شده را به عنوان یک خطا پرتاب می کند. باید آن را بگیریم و خطای خود را دوباره پرتاب کنیم:


let getUserProfile = async (userId) => {
  try {
    let response = await axios.get(`/user/${userId}`);
    return response.data;
  } catch (error) {
    // Do something smarter with `error` here
    throw new Error(`Could not fetch user profile.`);
  }
};

>

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

افزودن async به آرامی مقدار بازگشتی تابع شما را تغییر می‌دهد

من سردرگمی زیادی را دیده‌ام که از روی آوردن به async/wait برای افزودن تماس‌های ناهمزمان به یک تابع همگام قبلی حاصل شده است. ممکن است فکر کنید می‌توانید async و wait را اضافه کنید و بقیه موارد همانطور که انتظار می‌رود به کار خود ادامه می‌دهند. مسئله این است که توابع async وعده‌ها را برمی‌گردانند. بنابراین، اگر یک تابع را به ناهمزمان تغییر دهید، باید مطمئن شوید که همه فراخوانی‌های تابع موجود برای رسیدگی مناسب به یک وعده تنظیم شده است. اگر منصفانه باشیم، بررسی فراخوانی‌های تابع از قبل موجود نیز کاری است که باید در صورت استفاده از نحو سنتی قول انجام دهید، اما توابع ناهمزمان در مورد آن چندان واضح نیستند.

چرا سرمایه گذاری های هوش مصنوعی موفق نمی شوند؟

استفاده از async/await به معنای پرداختن به یک وعده است

وقتی یک تابع ناهمزمان را در جایی اضافه کردید، در سرزمین وعده هستید. باید مطمئن شوید که هر توابعی که تابع async را فراخوانی می کند، نتیجه را به عنوان یک وعده در نظر می گیرد یا از async/await استفاده می کند. اگر تابع async عمیقاً تو در تو باشد، پشته توابعی که منجر به فراخوانی آن تابع می شود نیز ممکن است توابع غیر همگام باشند. باز هم، این مشکل مختص async/await نیست و در وعده‌ها نیز مشکلی ایجاد می‌کند. با این حال، در برخی موارد، شما باید یک قول داشته باشید. اگر async/await را از طریق پشته تماس ادامه دهید، در نهایت به زمینه جهانی می‌رسید که نمی‌توانید از wait استفاده کنید. در جایی، باید با یک تابع همگام به روش سنتی و قول‌دهنده مقابله کنید.

استفاده از async/await نیاز به استفاده از try/catch نیز دارد

اگر از async برای رسیدگی به هر قولی که احتمالاً رد می‌شود استفاده می‌کنید، باید از try/catch نیز استفاده کنید، که یک ویژگی زبان پرکاربرد من دیده‌ام که تقریباً به طور انحصاری در کتابخانه‌ها استفاده می‌شود، جایی که تنها راه برای شناسایی ویژگی‌های خاص امتحان کردن آنها و یافتن خطاها بر اساس آن است. البته این یک تعمیم است، اما نظر من این است که می‌توان جاوا اسکریپت جامد و اصطلاحی را برای سال‌ها بدون نیاز به استفاده از try/catch نوشت. پذیرش async/await مستلزم آن است که try/catch را نیز بپذیرید.

نتیجه گیری

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

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