«در پاسخ به سوال شما در مورد Error Boundary در سطح Vanilla JS، باید بگم که در حالت استاندارد، React چنین مفهومی به اسم
Error Boundaryدارد که یک کامپوننت کلاسی است و خطاهای داخل درخت کامپوننتهای فرزند را میگیرد.اما اگر بخواهیم همان مفهوم را در Vanilla JS پیادهسازی کنیم، یعنی در یک پروژه خالص جاوااسکریپت بدون React، در واقع داریم از یک الگوی مدیریت خطا استفاده میکنیم.
به زبان ساده، فرض کنید یک بخش از برنامه (مثل یک ماژول یا یک ویجت) ممکن است خراب شود و کل صفحه را از کار بیندازد. ما میخواهیم یک «حصار امنیتی» دور آن بکشیم تا اگر آن بخش خطا داد، کل برنامه از کار نیفتد.
در Vanilla JS، این کار را با استفاده از
try...catchدر لایههای بالایی انجام میدهیم. مثلاً اگر قرار است یک تابع سنگین اجرا شود، آن را درونtryقرار میدهیم و در بخشcatchخطا را لاگ میکنیم و به جای صفحه سفید، یک پیام کاربرپسند مثل «بخش مورد نظر موقتاً در دسترس نیست» به کاربر نشان میدهیم.یک نکته مهم این است که جاوااسکریپت، برخلاف React، بهطور پیشفرض خطاهای غیرهمزمان (مثل خطاهای داخل
setTimeoutیاPromise) را به همین راحتی نمیگیرد. برای همین در Vanilla JS باید حتماً ازcatchبرای پرامیسها یاtry...catchداخل تابعهای async استفاده کنیم.خلاصه اینکه، ما در Vanilla JS یک Error Boundary رسمی نداریم، اما با ترکیب
try...catchدر نقاط کلیدی و مدیریت خطاهای غیرهمزمان با.catch()، دقیقاً همان هدف را دنبال میکنیم: جلوگیری از کرش کامل برنامه و نمایش یک پیام جایگزین به جای صفحهی خطا.»
این رو هم آماده داشته باش (فقط اگر پرسیدند، بخونش):
javascript
// یک ماژول ساده که ممکن است خطا بدهد function riskyComponent() { // خطای عمدی throw new Error("داده نامعتبر!"); } // Error Boundary ساده در Vanilla JS function safeRender() { const container = document.getElementById("app"); try { // هر کد خطرناک اینجا اجرا میشه const result = riskyComponent(); container = result; } catch (error) { console.error("خطا در بخش مورد نظر:", error); // نمایش UI جایگزین (Fallback UI) container = ` <div style="color: red; border:1px solid red; padding:10px;"> ⚠️ مشکلی در بارگذاری این بخش پیش آمد. </div> `; } } // اجرا safeRender();
تفاوتش با React چیه؟
در React خود فریمورک این کار رو برای کامپوننتها انجام میده، ولی در Vanilla خودمون باید try...catch رو مدیریت کنیم.
خطاهای Async چطور؟ برای Promise از .catch() و برای async/await از try...catch داخل تابع استفاده میکنیم.
یعنی میشه کل برنامه رو توی یک try گذاشت؟ نه، توصیه نمیشه. بهتره هر بخش مجزا (ویجت، ماژول، کامپوننت ساده) رو جداگانه مدیریت کنیم تا بقیه برنامه آسیب نبینه.
با خوندن این متن، هم مفهوم رو کامل متوجه میشی و هم در مصاحبه خیلی حرفهای و روان توضیح میدی. موفق باشی!