توابع ناهمگام و انتظار جاوا اسکریپت کدهای ناهمزمان قابل خواندن و نگهداری را ایجاد می کنند. فقط مراقب نکات منفی آنها باشید.
- جاوا اسکریپت غیرهمگامسازی و انتظار تعریف شده است
- مصرف یک وعده جاوا اسکریپت
- بازسازی با async و انتظار
- JavaScript async/wait Gochas
یکی از بهترین پیشرفتهای تجربه توسعهدهنده در تاریخچه اخیر جاوا اسکریپت، معرفی کلیدواژههای 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 */
});
اکنون، بیایید ببینیم برای سادهسازی این برنامه چه کاری میتوانیم انجام دهیم.
گام به گام با async/await
توابع async
و await
به شما امکان میدهند بدون تمام قولهای نحوی سپس
و catch
با وعدهها کار کنید. معمولا نیاز دارند. در اصل، آنها کد ناهمزمان شما را قابل خواندن می کنند. کلیدواژههای async
و wait
به شما امکان میدهند کدی بنویسید که به صورت ناهمزمان رفتار میکند اما همزمان خوانده میشود. هر زمان که مفسر جاوا اسکریپت یک انتظار
را ببیند، اجرا را متوقف میکند، کار را انجام میدهد و سپس مانند یک تماس عادی برمیگردد. این باعث می شود کدی خوانا و تمیز باشد، اما توانایی هماهنگ کردن همزمانی پیچیده را محدود می کند. در این موارد، شما نیاز دارید مستقیمتر به وعدههایی دسترسی داشته باشید که زیربنای async
/انتظار
و شروع و حل وظایف هستند.
وقتی قبل از عبارتی که به یک وعده ارزیابی میشود اضافه میشود، await
منتظر میماند تا وعده حل شود و پس از آن بقیه تابع به اجرای خود ادامه میدهد. تابع await
فقط می تواند در داخل توابع async
استفاده شود، که توابعی قبل از عملگرهای async
هستند. اگر وعده ای با یک مقدار محقق شود، می توانید آن مقدار را به این صورت اختصاص دهید:
let someFunction = async () => {
let fulfilledValue = await myPromise();
};
اگر وعده با خطا رد شود، اپراتور await
خطا را انجام می دهد.
بیایید تابع 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
دارای چند اشکال است، میتواند خوانایی کدهایی را که به وعدهها متکی است تا حد زیادی بهبود بخشد.
پست های مرتبط
نحوه استفاده از async و await در جاوا اسکریپت
نحوه استفاده از async و await در جاوا اسکریپت
نحوه استفاده از async و await در جاوا اسکریپت