ساختار async/await در ES7 معرفی شد که می تواند به عنوان جایگزینی برای ساختار promise در نظر گرفته شود، با استفاده از async/await می توانید خوانایی و سادگی کد برنامه را ارتقاء دهید.
برای مثال ساختار promise زیر را در نظر بگیرید :
function showLogs(cb) { UserModel.findById(1).then((err, user)=>{ if(err) cb(err); // other codes if(user) { UserLogModel.findById(user.id).then((err, logs)=>{ if(err) cb(err); console.log(logs); }) } else { cb(“No user found”); } }) }
در کد بالا مشخصات کاربر از پایگاه داده (mongodb) خوانده شده و در صورت یافت شدن کاربر، تاریخچه ورودهای کاربر را از پایگاه داده خوانده و در خروجی نمایش داده می شود. این کد بدون هیچ گونه خطایی کار می کند اما این ساختارهای promise که در چند سطح داخلی تکرار می شود(این مثال در دو سطح ذکر شده است اما بر اساس سناریوهای متفاوت این سطح می تواند بیشتر باشد) و یا به صورت chain هستند می تواند برای توسعه دهندگان تازه کار و حتی با تجربه کمی ناخوانا و پیچیده باشد، به همین دلیل ساختار async/await در ES7 معرفی شد تا این مسئله را بهبود ببخشد.
قطعه کد بالا با استفاده از ساختار async/await:
async function showLogs(cb) { const user = await UserModel.findById(1); if(user) { const logs = await UserLogModel.findById(user.id); console.log(logs); } else return cb(“No user found”); }
در ساختار بالا مشاهده می کنید که کد مورد نظر به مراتب خوانایی بهتری دارد. اما در این ساختار هنوز خطاها را مدیریت نکرده ایم، برای مدیریت خطاها باید از try...catch استفاده کنیم.
async function showLogs (cb) { try { const user = await UserModel.findById(1); if(!user) console.log('No user found'); } catch(e) { return cb(‘There is an error while getting user'); } try { const logs = await UserLogModel.findById(user.id); console.log(logs); } catch(e) { return cb('Error occurred while getting logs); } }
همانطور که مشاهده می کنید مدیریت خطاها در ساختار async/await باعث بیشتر شدن تعداد خطهای کد و کم شدن خوانایی برنامه می شود.
برای مدیریت بهتر خطاهای این ساختارمی توانید از کتابخانه await-to-js استفاده کنید. با ارسال قطعه کد مورد نظر به توابع این کتابخانه، کد در داخل تابع اجرا شده و در صورت بروز خطا، نوع خطا را به همراه نتیجه اجرای کد بر می گرداند.
import to from 'await-to-js'; async function showLogs (cb) { let err, user, logs; [err, user] = await to(UserModel.findById(1)); If (err) return cb(‘There is an error while getting user’); if(user) { [err, logs] = await to(UserLogModel.findById(user.id)); if(err) cb(‘'Error occurred while getting logs’); else console.log(logs); } else cb(‘No user found’); }