Javascript async/wait – انجمن DEV
در این مقاله، من به بحث در مورد کدهای ناهمزمان و به طور خاص تر نحوه استفاده از async/wait ادامه خواهم داد.
قبل از رفتن بیشتر، اگر میخواهم یک چیز را از این مقاله حذف کنید این است: در پایان روز، async/wait به ما امکان میدهد تا کدهای همگامسازی را بهجای تودرتوی بیپایان تماسهای برگشتی، به صورت همزمان بنویسیم.
نکات اصلی
1. هنگامی که از async/wait استفاده می کنیم، انتظار همیشه منتظر می ماند تا وعده حل شود.
2. ما فقط زمانی میتوانیم از await استفاده کنیم که در جلوی تابع، async داشته باشیم، این مهم است، زیرا اغلب زمانی که افراد async/wait را یاد میگیرند، مخصوصاً مبتدیان، تقریباً شروع به استفاده از await در سراسر کد خود میکنند و شما نمیتوانید این کار را انجام دهید. . فقط در صورتی میتوانید از انتظار استفاده کنید که عملکردی که تنظیم کردهاید واقعاً ناهمگام باشد.
تابع 3.async همیشه یک وعده را برمی گرداند.
NB: در طول این مقاله، من از تابع arrow استفاده خواهم کرد، اما اگر ترجیح می دهید از تابع سنتی استفاده کنید، هیچ قانونی علیه شما وجود ندارد، فقط آن را دنبال کنید.
مثال کلی
//نمایش نحوه عملکرد async همیشه یک وعده را برمی گرداند
const example = async ()=> {
return "Hello world"
}
console.log(example()) // it will show a promise in the console.
خروجی:
همانطور که می بینید، این یک وعده است و بلافاصله محقق می شود. فقط به خاطر داشته باشید که async همیشه و همیشه یک وعده را برمیگرداند.
//نمایش نحوه عملکرد await:
const example = async () =>{
return "Hello world";
}
const someFunc = async () =>{
const result = await example();
console.log(result);
}
someFunc();
خروجی:
از اینجا، await باید منتظر بمانید تا وعده تابع مثال حل شود، سپس می توانید نتیجه را در کنسول دریافت کنید. این بسیار مهم است زیرا مجبور نیستید به جای آن از زنجیره های .then() استفاده کنید، باید منتظر بمانید تا وعده حل شود و نتیجه را دریافت کنید.
مثال دنیای واقعی:
معمولاً، شما معمولاً منابع را از طریق سیم درخواست میکنید، یعنی از پایگاه داده، API یا هر چیز دیگری، اما در اینجا من از یک مثال ساده استفاده میکنم که در آن آرایه کاربر (شامل دانشجویان) و آرایه کلاسها (شامل موضوعات) دانشآموزان هستند. گرفتن
const users = [ // array of objects containing stundets and their ID
{id: 1, name:"kebean"},
{id: 2, name:"Chico"},
{id:3, name:"Maelle"},
]
const classes = [ // array of objects containing student ID and classes they are taking
{studentId:1, classesTaken:["OOP", "C", ".Net"]}, //kebean take this class because the ID matches
{studentId:2, classesTaken:["Math", "History"]}, //Chico take this class because the ID mathches
{studentId:3, classesTaken:["Physics", "Chemistry", "Geography"]} //Maelle take this class because the ID mathches
]
const getUser = (name) =>{
return new Promise((resolve, reject) =>{
const user = users.find((user) => user.name ===name);
if (user){
return resolve(user);
}else{
reject(`No such user with name: ${name}`);
}
})
}
const getClasses = studentId => {
return new Promise((resolve, reject) =>{
const userClasses = classes.find((user) => user.studentId === studentId)
if(userClasses){
return resolve(userClasses.classesTaken)
}else{
reject("Wrong ID")
}
})
}
NB: باید درک کنید که توابع بالا به ترتیب اتفاق می افتند، تنها زمانی که دانش آموز را دریافت کنید، تنها در این صورت می توانید به موضوعی که در حال مطالعه است دسترسی داشته باشید.
از آنجایی که با دو تابع بالا آشنا هستید، میخواهم نشان دهم که چگونه میتوانید دادهها را با استفاده از روش .then() معمولی دریافت کنید و بعداً نشان خواهم داد که چگونه میتوانید در حین استفاده از async/wait که مؤثرتر است، به همان چیزی دست پیدا کنید. حداقل از نظر من قابل خواندن است
رویکرد .then() معمولی
getUser("kebean") // returns a promise
.then((user) => console.log(user)) //you will have access to data you pass into resolve()
.catch((error) => console.log(error)) //when there is errors, you will catch them here
منطق به این صورت است: اگر نام مطابقت داشته باشد، نام را پاس می کنید، البته دانش آموز را دریافت می کنید و زمانی که نام مطابقت نداشته باشد، با پیغام خطا مواجه می شوید.
خروجی:
زمانی که کاربر وجود ندارد:
getUser("kebeans")
.then((user) => console.log(user))
.catch((error) => console.log(error))
همانطور که مشاهده می کنید پیغام خطا نمایش داده می شود
خروجی:
getUser("kebean")
.then((user) => getClasses(user.id)) //invoking getClasses and pass in the user ID
.then((classes) => console.log(classes)) //the getClasses function above, returns classes that match to the user ID or student ID you passed in
.catch((error) => console.log(error))
خروجی:
مشکل راهاندازی بالا این است که وقتی چندین عملیات async داشته باشید، باید این .then() را زنجیرهای کنید که خواندنی نیست و نوشتن طولانی است. اینجاست که async/wait واقعاً می درخشد، زیرا میتوانید کد بالا را با تنظیم مجدد کد برای استفاده از async/await خواناتر کنید.
رویکرد async/wait
const getStudent = async () =>{
const user = await getUser("kebean")
console.log(user)
}
getStudent()
خروجی:
از مثال بالا، می بینید که دسترسی به دانش آموز با استفاده از async/wait امکان پذیر است. بیایید ببینیم چگونه میتوان به کلاسهایی که دانشآموز میتواند در آن شرکت کند، دسترسی پیدا کرد.
const getStudent = async () =>{
const user = await getUser("kebean");
if(user){
const classes = await getClasses(user.id);
console.log(classes)
}
}
getStudent()
خروجی:
رونق!! می توانید کلاس هایی را که kebean می گذراند نیز دریافت کنید.
فقط نگاهی به کد در هر دو رویکرد بیندازید، منظورم این است که حتی اگر کد تقریباً یک کار را انجام میدهد، به وضوح میتوانید ببینید که رویکرد استفاده از async/wait بسیار خواناتر و کوتاهتر است.
نحوه رسیدگی به خطاها هنگام استفاده از async/wait
همانطور که می بینید، هنگام استفاده از async/wait نمی توان آنطور که انتظار می رود، با خطا برخورد کرد. به کد زیر دقت کنید:
const getStudent = async () =>{
const user = await getUser("kebeans");
if(user){
const classes = await getClasses(user.id);
console.log(classes)
}
}
getStudent()
خروجی:
همانطور که می بینید، student(user) “kebeans” (با “s” در انتها) وجود ندارد و به جای دریافت پیغام خطای تعریف شده در reject()، در کنسول و آنچه نیاز دارید آشفته می شوید. این است که آن را با ظرافت اداره کنیم. می توانید این کار را با راه اندازی بلوک try and catch مانند زیر انجام دهید:
const getStudent = async () =>{
try {
const user = await getUser("kebeans");
if(user){
const classes = await getClasses(user.id);
console.log(classes)
}
} catch (error) {
console.log(error)
}
}
getStudent()
خروجی:
نتیجه
امیدواریم، اکنون به وضوح میتوانید ببینید که چرا هنگام نیاز به انجام وظایف ناهمزمان، async/wait تقریباً به ابزاری تبدیل شده است.
این خوانایی را با اجازه دادن به ما برای نوشتن کدهای ناهمزمان به سبک همگامتر بهبود میبخشد و خواندن و درک آن را آسانتر میکند. این همچنین می تواند به ویژه برای توسعه دهندگانی که در برنامه نویسی ناهمزمان تازه کار هستند مفید باشد.
با تشکر از خواندن و کد نویسی خوشحال!
سفارشی.