Async و Await در جاوا اسکریپت – توضیح به زبان ساده + مثال و کد
در زبان برنامه نویسی جاوا اسکریپت، کلمات کلیدی «Async» و «Await» «سینتکسی» (Syntax) جدید هستند که به مدیریت عملیات ناهمزمانی کمک میکنند. در این مطلب آموزش از مجله فرادرس موضوع Async و Await در جاوا اسکریپت و ابعاد مختلف آن پوشش داده خواهد شد تا کاربران بتوانند در آخر عملیات ناهمزمانی را در جاوا اسکریپت یاد بگیرند.
ناهمزمانی در جاوا اسکریپت چیست؟
زبان برنامه نویسی جاوا اسکریپت شامل عملیات خاصی است که ناهمزمان هستند، به این معنی که مقدار یا نتیجه تولید شده فوراً در دسترس نخواهد بود، این موضوع به نام جاوا اسکریپت ناهمزمان شناخته میشود.
قطعه کد زیر برای درک این موضوع است:
1function fetchDataFromApi() {
2 // Data fetching logic here
3 console.log(data);
4}
5
6fetchDataFromApi();
7console.log('Finished fetching data');
به دلیل ماهیت ناهمزمان تابع fetchDataFromApi ، مفسر جاوا اسکریپت قبل از ادامه دستورات بعدی، منتظر تکمیل آن نمیماند. در نتیجه، قبل از ثبت اطلاعات واقعی بهدستآمده از API، فرایند Finished Fetching را ثبت میکند. در بسیاری از شرایط، این عملیات مورد نظر نیست. خوشبختانه، میتوان از ویژگی Async در جاوا اسکریپت استفاده کرد و منتظر این کلمات کلیدی ماند تا برنامه قبل از ادامه، منتظر پایان عملیات ناهمزمان باشد. این ویژگی در «ES2017» به جاوا اسکریپت معرفی شد و توسط تمام مرورگرهای امروزی پشتیبانی میشود.
نحوه ایجاد تابع Async در جاوا اسکریپت
در این بخش از آموزش Async و Await در جاوا اسکریپت، منطق بازیابی اطلاعات تابع fetchDataFromApi عمیقتر مورد بررسی قرار خواهد گرفت. fetchDataFromApiنمونهای معمولی از عملیات ناهمزمان در جاوا اسکریپت است.
همانطور که در کدهای زیر نشان داده شده، میتوان از Fetch API در جاوا اسکریپت برای رسیدن به این هدف استفاده کرد:
1function fetchDataFromApi() {
2 fetch('https://v2.jokeapi.dev/joke/Programming?type=single')
3 .then(res => res.json())
4 .then(json => console.log(json.joke));
5}
6
7fetchDataFromApi();
8console.log('Finished fetching data');
در سناریوی بالا، یک جوک برنامه نویسی از «JokeAPI» بازیابی شده است. پس از پاسخ API که با فرمت «JSON» خواهد بود، اطلاعات با استفاده از متد json() استخراج میشوند و سپس لطیفه مربوط به کنسول خروجی داده خواهد شد. توجه به این نکته ضروری است که از آنجایی که JokeAPI نوعی API شخص ثالث محسوب میشود، پس نمیتوان از کیفیت جوکهایی که برمیگرداند اطمینان حاصل کرد. اگر این کد در مرورگر یا در «نود جی اس» (Node.js) اجرا شود، امکان دارد که خروجی کنسول هنوز ترتیب درستی نداشته باشد.
کلمه کلیدی Async در جاوا اسکریپت چیست؟
برای فعال کردن رفتار ناهمزمان در توابع جاوا اسکریپت، میتوان از کلمه کلیدی Async قبل از کلمه کلیدی تابع استفاده کرد. برای مثال، اجازه دهید تابعی به نام fetchDataFromApi() را در نظر بگیریم که دادهها را از یک API واکشی میکند.
همانطور که در ادامه نشان داده شده است، میتوان با استفاده از کلمه کلیدی Async در جاوا اسکریپت آن را ناهمزمان کرد:
1async function fetchDataFromApi() {
2 fetch('https://v2.jokeapi.dev/joke/Programming?type=single')
3 .then(res => res.json())
4 .then(json => console.log(json.joke));
5}
وقتی تابعی به عنوان ناهمزمان علامتگذاری میشود، همیشه «وعده» (Promise) را برمیگرداند. میتوان متد then() را به فراخوانی تابع زنجیره زد تا اطمینان حاصل شود که ترتیب اجرا درست است. برای مثال، میتوان تابع fetchDataFromApi()را فراخوانی کرد و سپس متدthen()را مانند کد زیر به آن زنجیره زد:
1fetchDataFromApi()
2 .then(() => {
3 console.log('Finished fetching data');
4 });
پس از اجرای کد، دادههای واکشی شده و پیام 'Finished fetching data' به عنوان خروجی دریافت خواهند شد و چیزی مشابه خروجی زیر را بیرون خواهد داد:
If Bill Gates had a dime for every time Windows crashed ... Oh wait, he does. Finished fetching data
با این حال، سینتکس Promise در جاوا اسکریپت میتواند برای خواندن پیچیده و چالشبرانگیز شود و اینجاست که Async و Await در جاوا اسکریپت مفید واقع خواهند شد. این ویژگی به کاربران امکان میدهد کدهای ناهمزمان بنویسند، در حالی که این کدها بیشتر شبیه کدهای همزمان بوده و خواندن آنها آسانتر است.
کلمه کلیدی Await در جاوا اسکریپت
برای اینکه عملیات ناهمزمان را متوقف کنیم و منتظر نتیجه بمانیم، باید از کلمه کلیدی Await در مقابل آن عملیات در تابع استفاده کرد. سپس میتوان نتایج این عملیات را به متغیرها اختصاص داد.
برای مثال، اجازه دهید تابع fetchDataFromApi()را که قبلاً به عنوان ناهمزمان علامتگذاری کرده بودیم در نظر بگیریم. میتوان از کلمه کلیدی Await برای توقف اجرا تا زمانی استفاده کرد که نتیجه فراخوانی API دریافت میشود و نتیجه را به یک متغیر اختصاص میدهد. سپس میتوان از کلمه کلیدی Await دیگری برای توقف اجرا استفاده کرد و منتظر پاسخ JSON از تماس API ماند. در نهایت، میتوان ویژگی joke پاسخ JSON را به کنسول وارد کرد. در اینجا سینتکس تغییر تابع fetchDataFromApi()با استفاده از کلمه کلیدی Await آمده است:
1async function fetchDataFromApi() {
2 const res = await fetch('https://v2.jokeapi.dev/joke/Programming?type=single');
3 const json = await res.json();
4 console.log(json.joke);
5}
همچنین باید منتظر نتیجه فراخوانی تابع fetchDataFromApi()ماند که قطعه کد آن به صورت زیر است:
1await fetchDataFromApi();
2console.log('Finished fetching data');
برای اطمینان از صحیح بودن دستور اجرا، باید منتظر نتیجه فراخوانی تابع fetchDataFromApi()بمانیم. میتوان با استفاده از کلمه کلیدی Await دوباره به این هدف رسید. با این حال، اگر کاربر بخواهد از انتظار خارج از تابعی ناهمزمان در اسکریپت غیر ماژول استفاده کند، با خطای زیر مواجه خواهد شد.
Uncaught SyntaxError: await is only valid in async functions, async generators and modules
برای حل این مشکل، میتوان کد فراخوانی را در تابعی دیگر قرار داد و آن را به عنوان ناهمزمان علامتگذاری کرد و سپس عمل فراخوانی را انجام داد. مثال زیر برای درک این موضوع مهم است:
1async function fetchDataFromApi() {
2 const res = await fetch('https://v2.jokeapi.dev/joke/Programming?type=single');
3 const json = await res.json();
4 console.log(json.joke);
5}
6
7async function init() {
8 await fetchDataFromApi();
9 console.log('Finished fetching data');
10}
11
12init();
اکنون اگر کدها اجرا شوند، همه چیز باید به ترتیب درست مانند خروجی زیر نمایش داده شود:
UDP is better in the COVID era since it avoids unnecessary handshakes. Finished fetching data