<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Alireza Taji</title>
        <link>https://virgool.io/feed/@alirezataji6</link>
        <description>backend developer | telegram : @ali256reza</description>
        <language>fa</language>
        <pubDate>2026-06-16 18:27:09</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/144037/avatar/9gPv2y.jpg?height=120&amp;width=120</url>
            <title>Alireza Taji</title>
            <link>https://virgool.io/@alirezataji6</link>
        </image>

                    <item>
                <title>نکات امنیتی که حین توسعه حتما باید رعایت کنید</title>
                <link>https://virgool.io/smartsystemco/%D9%BE%DB%8C%D8%B4%DA%AF%DB%8C%D8%B1%DB%8C-%D9%87%D8%A7%DB%8C-%D8%A7%D9%85%D9%86%DB%8C%D8%AA%DB%8C-%D9%87%D9%86%DA%AF%D8%A7%D9%85-%D8%AA%D9%88%D8%B3%D8%B9%D9%87-%D8%A7%D9%BE%D9%84%DB%8C%DA%A9%DB%8C%D8%B4%D9%86-%D8%A8%D8%AE%D8%B4-%D8%A7%D9%88%D9%84-m44ryslyuwwg</link>
                <description>هنگام توسعه اپلیکیشن باید دقت زیادی برای حفاظت از اطلاعات، مدیریت دسترسی و کنترل عملکرد کاربران به خرج داد.توی این پست به یک سری از اقدامات مهمی که نیاز هست مد نظر قرار بدید اشاره می کنم:اپلیکیشن را با دسترسی های root اجرا نکنیدیکی از اصول امنیتی که همیشه باید رعایت بشه دادن حداقل دسترسی های مورد نیاز به کاربران برای انجام کارشان هست. هنگام اجرا کردن اپ با دسترسی root ریسک حملات command injection رو افزایش میدید (در این نوع از حمله مهاجم یک اسکریپت به عنوان ورودی در محلی از برنامه که با هدف اجرا کردن کامند توسعه داده شده وارد می کند)هدر x-powered-by را غیر فعال کنیدبا انجام این کار شانس تشخیص فریم ورکی که با استفاده از آن API خود را توسعه دادید پایین تر میاوریدقرار ندادن پسورد ها، توکن ها و سایر اطلاعات مهم اپ داخل گیت پروژهبه هیچ عنوان اطلاعات مهم امنیتی رو داخل ریپازیتوری گیت نیارید (اطلاعاتی مثل یوزر پسورد دیتابیس ها، توکن سرویس های thrid party و ...) و اون ها رو به عنوان متغیر های محیطی ذخیره کنید و به اپلیکیشن بدید (environment variables)جلوگیری از حملات DDoSبا ست کردن rate limit تعداد درخواست های کاربران را مدیریت کنیدDDoS به حملاتی گفته می شود که مهاجم با ایجاد اختلال در ارتباط با سرور به وسیله درخواست های بیش از حد، ارتباط دیگر کاربران را دچار تداخل می کندrate limit عملیاتی هست که تعداد درخواست های کاربر را در بازه زمانی معین کنترل می کندجلوگیری از password guessingهنگامی که کاربر پسورد خود را ثبت می کند باید ساختار آن را کنترل کنید تا ساده نباشد با اینکار شانس پیدا کردن پسورد رو برای مهاجم ها سخت تر می کنید برای لاگین rate limit جداگانه و با محدودیت بیشتر ست کنید با اینکار از حملات brute force جلوگیری می کنیدجلوگیری از XSSمهاجم داخل ورودی ها کد جاوااسکریپت می گذارد و مرورگر آن کد را هنگام نمایش اجرا می کندنکته: اگر از ری اکت برای توسعه فرانت اند استفاده می کنید با این نوع حملات مواجه نمی شویدبرای جلوگیری از این حملات باید ورودی های کاربر را validate کنیدحمله insecure DORهنگام دریافت اطلاعات کاربر، آیدی کاربر را از توکن کاربر بگیرید نه از طریق دیتای درخواست.هنگام دانلود فایل های حساس، دسترسی کاربر به آن فایل رو چک کنید و به hash کردن نام فایل اکتفا نکنید.محدود کردن سایز body درخواست هایک محدودیت حجمی برای سایز درخواست های http بگذارید (مثلا ۱ مگابایت برای json body و ۱۰ مگابایت برای فایل)جلوگیری از sql injectionدر این نوع از حملات مهاجم در کنار ورودی ای که به اسکریپت sql خود میدهید یک اسکریپت دیگری وارد می کند که منجر به دسترسی به دیتاهایی خارج از دسترسی کاربر می شودSELECT * FROM Users WHERE UserId = &amp;quot + userId;
// userId = 3 OR 1=1در مثال بالا با پاس دادن مقدار کامنت شده به جای userId می توانیم لیست تمام کاربران رو بگیریمنکته: orm ها با استفاده از parametrized-query ها از این حمله جلوگیری می کنند اما زمانی که raw query میزنید باید ورودی های کوئری کاربر را validate کنیداستفاده از CSRF توکنهنگامی که توکن رو با session یا کوکی های سمت سرور (http only) ذخیره می کنید حتما باید برای api ها توکن csrf ست کنید، در غیر این صورت با ارسال یک ایمیل مخرب و باز کردن آن توسط شما، مهاجم می تواند با توکن شما درخواست بزند(توضیحات نحوه اتفاق افتادن این حمله طولانیه شاید توی یک پست دیگه توضیح بدم)هش کردن دیتای حساسهنگامی که اطلاعات احراز هویتی حساسی را از کاربر ذخیره می کنید، آن ها را به صورت یک طرفه hash کنید (با این کار دیگر نمی توان به دیتای اصلی دست پیدا کرد و فقط امکان مقایسه یکسان بودن دیتای اصلی با دیتای hash شده وجود دارد) اطلاعاتی مثل پسورد، access token (در صورت ذخیره کردن روی دیتابیس) و ... با این کار عواقب لو رفتن دیتا های دیتابیس به مراتب کمتر می شوداستفاده از توکن checksumدر سیستم هایی که اطلاعات احراز هویتی از اهمیت بسیار بالایی برخوردار هستند، اطلاعات حساس کاربر (یوزرنیم، شماره تماس، پسورد و ...) را در کنار هم قرار می دهیم و آن عبارت را hash می کنیم و به عنوان  ستون checksum داخل دیتابیس نگه میداریم و هنگام درخواست های کاربر هر بار اطلاعات را با توکن مقایسه می کنیم و در صورت مقایرت داشتن اپلیکیشن را shutdown می کنیم(وقتی که یک نفر مستقیما از طریق دیتابیس یکی از اطلاعات کاربر را تغییر دهد این مغایرت رخ می دهد)نکته: استفاده از checksum پرفورمنس رو کاهش میده و فقط در مواقع ضرورت از اون باید استفاده کردامیدوارم مفید بوده باشه- علیرضا تاجی</description>
                <category>Alireza Taji</category>
                <author>Alireza Taji</author>
                <pubDate>Sun, 14 May 2023 20:24:49 +0330</pubDate>
            </item>
                    <item>
                <title>دیزاین پترن ها - Proxy Design Pattern</title>
                <link>https://virgool.io/smartsystemco/%D8%AF%DB%8C%D8%B2%D8%A7%DB%8C%D9%86-%D9%BE%D8%AA%D8%B1%D9%86-%D9%87%D8%A7-proxy-design-pattern-qzt1qcyijhhv</link>
                <description>برای اقدام کردن در هر زمینه ای حجم زیادی از داده ها وجود داره که برای انجام یک سری کار مشخص ما فقط به اندکی از اون داده ها نیاز داریم و با سایر اون ها ممکنه هیچوقت درگیر نشیم ...برای نابرنامه‌نویس ۸۰ سالهتوی این بخش مسئله رو قرار هست به ساده ترین شکل ممکن توضیح بدم که حتی شخصی که برنامه نویس نیست و ۸۰ سال سن داره هم متوجه مفهوم محتوا بشهفرض کن وارد یک دعوای حقوقی شدی ولی هیچ اطلاعاتی از شیوه انجام امور حقوقی نداری پس یک منبع برای یادگرفتن قانون پیدا می کنی.وقتی شروع به خوندن می کنی با حجم زیادی از اصطلاحات تخصصی و قوانین متعددی که خیلی از اون ها به کارت نمیاد میشی.برای حل کردن این مشکل نیاز به یک وکیل (همون proxy ما) داری که با پیچیدگی های قانون آشنایی داره و اصطلاحات تخصصی مورد نیاز رو بلده. شما فقط برای مواردی که با اون ها درگیر هستی، از وکیلت کمک می خوای و دیگه با پیچ و خم قوانین مستقیما درگیر نمیشی.از دیزاین پترن proxy چه زمانی استفاده میشه؟دیزاین پترن proxy کلاسی جایگزین برای استفاده از یک منبع خارجی ارائه میدهد و دسترسی را به منبع اصلی کنترل می کندبرای مثال از کتابخانه ای برای ارتباط با فایل سیستم استفاده می کنی و متد های متعددی برای استفاده  وجود داره ولی در برنامه شما فقط به خواندن، نوشتن و حذف کردن فایل ها نیاز داری در این صورت یک کلاس FileSystem ایجاد می کنی و داخل اون سه متد با نام های read, create, delete تعریف می کنیو داخل هر کدوم از این متد ها، متد های کتابخانه اصلی رو فراخوانی می کنی و دیگه همه جا توی برنامه بجای استفاده مستقیم از کتابخانه از کلاس FileSystem که پروکسی ما هست استفاده می کنی.مزایای پیاده سازی این دیزاین پترن:فقط متد هایی که مورد نیاز هستند ارائه می شوندمی توانید عملیات هایی برای قبل یا بعد از اجرای عملیات اصلی در نظر بگیریدمی توانید نوع یا ساختار نتیجه متد اصلی را تغییر دهیدسایر توسعه دهندگان نیازی به آشنایی با کتابخانه مورد استفاده شما ندارند و فقط از متد های شما استفاده می کنندامیدوارم مفید بوده باشه- علیرضا تاجی</description>
                <category>Alireza Taji</category>
                <author>Alireza Taji</author>
                <pubDate>Wed, 10 May 2023 02:40:50 +0330</pubDate>
            </item>
                    <item>
                <title>Clean Code: DRY &amp; YAGNI</title>
                <link>https://virgool.io/smartsystemco/clean-code-dry-yagni-pwktauw8jh4m</link>
                <description>توی این مجموعه از پست های Clean Code قصد دارم تعدادی از نکات مهم رو بگم که شاید بدیهی به نظر برسن ولی در خیلی از موارد اون ها رو رعایت نمی کنیماین نکات مثل نمک توی غذا هستن بدیهی به نظر میان ولی اگر رعایت نشن غذا خوردن ندارهاصل DRY (یا Don&#x27;t Repeat Yourself)هر قسمت از کدت که چیزی رو تکرار کردی این اصل رو زیر پا گذاشتیمثال:function a() {
//..... extra logic
return { data: &#039;text-a&#039;, successful: true };
}function b() {
//..... another extra logic
return { data: &#039;text-b&#039;, successful: true };
}توی مثال بالا با تکرار کردن این عبارت ما این اصل رو نقض کردیم:{ data: , successful: }نمونه بهبود یافته که این اصل رو رعایت کرده باشیم:class Result {
  constructor(data, successful) {
    this.data = data;
    this.successful = successful;
  }
}function a() {
  return new Result(&#039;text-a&#039;, true);
}function b() {
  return new Result(&#039;text-b&#039;, false);
}حالا توی کد بالا دیگه اون عبارت رو تکرار نکردیم شاید تکرار کردن یک عبارت ساده توی کدتون در نگاه اول مشکلی ایجاد نکنه اما رعایت کردن این اصل توی تمام بخش های کدتون باعث میشه به ساختار بهتری برسید و مجبور بشید تا اصول دیگه ای هم در کنارش رعایت کنید حالا با رعایت دو تا نکته دیگه می تونیم کدمون رو باز هم تمیز تر کنیم۱. بهتره که توابع تا حد ممکن ورودی کمتری داشته باشند۲. inheritence (یکی از مفاهیم OOP هست) با ارث بردن از یک کلاس دیگه می تونیم از متد ها و پراپرتی های اون کلاس رو استفاده کنیم و در صورت نیاز تغییر بدیمنمونه کد بهبود یافته:class Result {
  constructor(data, successful) {
    this.data = data;
    this.successful = successful;
  }
}class SuccessResult extends Result {
  constructor(data) {
    super()
    this.successful = true;
    this.data = data;
  }
}class FailureResult extends Result {
  constructor(data) {
    super()
    this.successful = false;
    this.data = data;
  }
}function a() {
  return new SuccessResult(&#039;text-a&#039;);
}function b() {
  return new FailureResult(&#039;text-b&#039;);
}توی این کد ما دو تا کلاس مختلف رو استفاده می کنیم که فقط به اون ها یک پارامتر به عنوان ورودی میدیم ولی ما با انجام این کار دو تا مشکل برای خودمون ایجاد کردیم:هر برنامه نویسی بخواد با کد ما آشنا بشه باید تعداد زیادی کلاس و توابع مختلف رو باهاش آشنا بشه که شاید خیلی کم استفاده شده باشندقابلیت ها و وابستگی های کد رو بیش از حد نیازمون افزایش دادیمYAGNI (You Aren&#x27;t Gonna Need It)این اصل هم میگه کدی که الان نیازش نداری رو ننویسمثال:اگر نیاز داری یه عبارت عددی رندوم بسازی، لازم نیست یک تابع بنویسی که هم بتونه با اعداد عبارت رندوم بسازه، هم با حروفچون در حال حاضر شما نیازی به ساختن عبارتی که از حروف ساخته شده باشه ندارید و فقط عبارتی می خواید که از اعداد ساخته شده باشه، اگر بعدا نیاز داشته باشید بعدا می نویسیدشیک حالت دیگه ای هم که باید رعایت بشه توی همون مثال آخر DRY گفته شدهشما نباید وابستگی ها و قابلیت های کدتون رو بیشتر از حد نیاز کنید- علیرضا تاجی</description>
                <category>Alireza Taji</category>
                <author>Alireza Taji</author>
                <pubDate>Tue, 07 Feb 2023 14:39:34 +0330</pubDate>
            </item>
                    <item>
                <title>سناریو سیستم های رزرواسیون</title>
                <link>https://virgool.io/yaditon/%D8%B3%D9%86%D8%A7%D8%B1%DB%8C%D9%88-%D8%B3%DB%8C%D8%B3%D8%AA%D9%85-%D9%87%D8%A7%DB%8C-%D8%B1%D8%B2%D8%B1%D9%88%D8%A7%D8%B3%DB%8C%D9%88%D9%86-%D8%B9%D9%84%DB%8C%D8%B1%D8%B6%D8%A7-%D8%AA%D8%A7%D8%AC%DB%8C-q5qrc3s7qqcc</link>
                <description>یه چالش خیلی مهم سیستم های رزرواسیون اینه:نمایی از کنسرت اصغر آقااصغر آقا یه کنسرت برگذار می کنه با تعداد مشخصی صندلی و تو سایت هوشنگ و برادران IT تعداد بلیط ها رو ثبت می کنه که مردم بیان بخرنبعد چند روز بلیط ها فروخته میشه و فقط یک بلیط می مونهمن میرم بلیط رو بخرم، روی دکمه پرداخت کلیک می کنم میرم داخل درگاه پرداختاطلاعات رو وارد می کنم و پرداخت رو انجام میدم بعدش هم ریدایرکت میشم به سایت یه دفعه می بینم ارور میده:ظرفیت این کنسرت پر شده است!یعنی چی؟ مگه ننوشته بود یک بلیط موجوده؟ اصلا اگر ظرفیت پر شده چرا گذاشت پرداخت کنم؟ماجرا اینه:همون لحظه که من روی پرداخت زدم یه نفر دیگه هم همین کار رو کرده ، فقط چون سرعت عمل اون بیشتر از من بوده سریع تر اطلاعات کارت رو وارد کرده و بلیط رو خریده و برای اون ثبت شدهخب این یعنی مشکل از سرعت عمل پایین منه؟خیر!سیستم باید به این شکل پیاده سازی شده باشه:وقتی من روی دکمه پرداخت میزنم یکی از بلیط ها رزرو شده محسوب بشه و یک تراکنش برام ثبت بشهاینجوری دیگه کسی نمی تونه بیاد زود تر من پرداخت بزنه و بلیط بخرهمن وسط پرداخت به این فکر می کنم حالش رو ندارم کنسرت برم بیخیال میشم-‌ خب اینجوری که یه بلیط رزرو شده توی سیستم ولی پرداخت نداشتیمباید چک کنیم بعد از پانزده دقیقه نتیجه تراکنش چی بوده؟ آیا پرداخت موفقیت آمیز بوده یا نبوده؟ (با کرون جابز این کار رو انجام میدیم)اگر پرداخت موفقیت آمیز بود که هیچیاگر موفقیت آمیز نبود میام اون بلیطی که رزرو شده حساب کردیم رو از حالت رزرو در میاریم و میزاریم کاربر بعدی بیاد بخرهامیدوارم مفید بوده باشه :)</description>
                <category>Alireza Taji</category>
                <author>Alireza Taji</author>
                <pubDate>Tue, 05 Oct 2021 17:40:21 +0330</pubDate>
            </item>
                    <item>
                <title>سناریو سیستم احراز هویت (بخش لاگین)</title>
                <link>https://virgool.io/@alirezataji6/%D8%B3%D9%86%D8%A7%D8%B1%DB%8C%D9%88-%D8%B3%DB%8C%D8%B3%D8%AA%D9%85-%D8%A7%D8%AD%D8%B1%D8%A7%D8%B2-%D9%87%D9%88%DB%8C%D8%AA-%D8%A8%D8%AE%D8%B4-%D9%84%D8%A7%DA%AF%DB%8C%D9%86-fqep6dcodzgk</link>
                <description>توی قسمت قبلی این سری آموزش در مورد بخش Signup توضیح دادم.الان می خوام در مورد لاگین صحبت کنمکاربر ما وارد سایت میشه اکانت خودش رو میسازه و اطلاعاتش توی دیتابیس ثبت میشه حالا از اپ logout می کنه و می خواد دوباره وارد بشه پس باید login انجام بدهدو حالت پیش میاد :با شماره تماس می خواد وارد اکانتش بشه و نمی خواد رمزش رو وارد کنه (linear login)با شماره تماس یا نام کاربری و رمز عبورش می خواد وارد اکانت بشه نکته: در هر دو روش باید چک کنیم کاربری با این شماره تماس یا نام کاربری توی دیتابیس وجود داره اگر نداشت اجازه ورود ندارهLinear login (یا Passwordless login)اینجا شماره تماس کاربر رو می گیریم از طریق سامانه sms براش یک کد تایید می فرستیم و اون کد رو توی ردیس ذخیره می کنیمیه روت جدید میسازیم برای تایید کد به نام verify اونجا شماره تماس و کد تایید رو از کاربر می گیریم و چک می کنیم آیا این کد برای همین شماره تماس فرستاده شده یا نه؟اگر درست بود یه توکن JWT به کاربر میدیمPassword Loginشماره تماس و پسورد کاربر رو می گیریم اول از دیتابیس کاربری که این شماره تماس داره رو می گیریمبعدش میریم که ببینیم پسورد کاربر درسته یا نه؟اینجا با یه جالش رو به رو میشیموقتی پسورد رو hash کردیم و داخل دیتابیس ذخیره کردیم، چجوری مقایسه کنیم با پسورد اصلی که کاربر داده؟الان نوبت متد compare میشه که میاد چک می کنه آیا این پسورد نسخه هش شده این پسورد هست؟ (روشی که این کار رو انجام میده رو توی یه پست دیگه توضیح میدم)اگر پسورد درست بود یه توکن JWT به کاربر میدیمدر بخش های بعد authentication , authorization هم توضیح میدم ممنون که مطالعه کردید :)</description>
                <category>Alireza Taji</category>
                <author>Alireza Taji</author>
                <pubDate>Fri, 14 May 2021 18:28:33 +0430</pubDate>
            </item>
                    <item>
                <title>امنیت (node.js (Injections</title>
                <link>https://virgool.io/WebDevelopers/%D8%A7%D9%85%D9%86%DB%8C%D8%AA-%D8%AF%D8%B1-%D9%88%D8%A8-%D8%B3%D8%A7%DB%8C%D8%AA-%D9%87%D8%A7%DB%8C-nodejs-injections-clsilt75naf7</link>
                <description>چند نوع از injection ها رو در این قسمت مقاله بررسی می کنیم :JS Injectionهرگز هرگز هرگز ورودی های یوزر رو به عنوان یک پارامتر از eval , setTimeout , setInterval عبور ندید!!!تابع eval یک استرینگ رو می گیره و اون رو اجرا می کنهتوابع setTImeout, setInterval یک فانکشن به عنوان کالبک میگیرند و اون رو اجرا می کنندیک مثال ساده ://...
const username = &#039;process.exit()&#039;;
eval&#40;username&#41;;
//...وقتی که شما کد رو اجرا کنید پراسس نود جی اس بسته میشه.FS Injectionمانند مثال بالا اگر ورودی یوزر رو به عنوان پارامتر از توابع eval , setTimeout , setInterval عبور بدیم هکر می تونه فایل های داخل سرور رو ببینه ، اون ها رو بخونه و اون ها رو تغییر بده یا حذف کنه‌!یک مثال برای این نوع از حملات ://...
router.post(&#039;/get-username&#039;, (req, res) =&gt; {
    res.send(eval&#40;req.body.username&#41;);
}اگر یوزر به این روتر در خواست بزنه و username این عبارت بذاره :request-body :
{
    username : &amp;quotrequire(&#039;fs&#039;).readdirSync(&#039;.&#039;).toString()&amp;quot
}می تونه تمام فایل های داخل مسیر فعلی کد ببینه.چطور باید از این حملات جلوگیری کنیم‌‌؟۱. ورودی های یوزر رو validate کنید ( می تونید از پکیج هایی مثل joi , fastest-validator‌‌ استفاده کنید )۲. ورودی های یوزر رو از توابعی که بالا گفته شد به عنوان پارامتر عبور ندیدNoSql Injectionهکر می تونه با استفاده از این ترفند به اطلاعاتی که نباید دسترسی پیدا کنه ، دسترسی پیدا کنه یا تغییر در اون ها اعمال کنه!به طور مثال حمله کننده می خواد با استفاده از نام کاربری یکی دیگه وارد بشه ولی رمزش رو نداره.//...
router.post(&#039;/login&#039;, (req, res) =&gt; {
    User.findOne({ 
        username : req.body.username,
        password : req.body.password
    }).then(user =&gt; res.send(user);
}هکر از این ترفند استفاده می کنه تا به حساب کاربری دسترسی پیدا کنه :request-body : {
     username : &amp;quotalireza&amp;quot, 
     password : { $gt : &amp;quot&amp;quot }
}مانگو دی بی اطلاعات یوزری رو می فرسته که :username اون alireza باشه و password اون بزرگتر از &quot;&quot; باشه (یعنی هر پسوردی)چطور باید از این حملات جلوگیری کنیم‌‌؟1. ورودی های یوزر رو sanitize کنید ( می تونید از پکیج های mongo-sanitize , express-mongo-sanitize استفاده کنید)۲. از $eq  استفاده کنید۳. یک ورودی رو به عنوان کوئری پیدا کنید و بقیه اطلاعاتی که باید چک کنید رو از طریق if چک کنیدتوی سری های بعدی امنیت در وب سایت های node.js به سایر مباحث امنیتی هم می پردازیم‌:)</description>
                <category>Alireza Taji</category>
                <author>Alireza Taji</author>
                <pubDate>Sun, 20 Dec 2020 19:17:46 +0330</pubDate>
            </item>
                    <item>
                <title>پرامیس ها در جاوااسکریپت | Promises in JavaScript</title>
                <link>https://virgool.io/WebDevelopers/%D9%BE%D8%B1%D8%A7%D9%85%DB%8C%D8%B3-%D9%87%D8%A7-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-promises-in-javascript-prgn77jugf5v</link>
                <description>برای این که پرامیس ها رو بفهمیم باید اول این موضوعات رو بررسی کنیم :Blocking vs Non-Blockingعملگر هایی که یک ترد thread اپلیکیشن جاوا اسکریپت رو مشغول می کنند ( به اصطلاح بلاک می کنند ) ‌، عملگر های blocking هستند.حالا مشکل این عملگر ها کجاست‌؟- جاوااسکریپت فقط یک ترد داره و وقتی اون ترد درگیر بشه باید صبر کنه تا اون ترد آزاد بشه بعد به بقیه در خواست ها پاسخ بده!ولی ما این مشکل رو با عملگر های non-blocking نداریم چون این عملگر ها ترد رو به طور کامل مشغول نمی کنند.عملگر های blocking به صورت synchronous کار می کنند و عملگر های non-blocking به صورت asynchronous کار می کنند.به طور ساده تر بخوام بگم ، یک رستوران گارسون های زیادی داره و برای ثبت سفارش مشتری ها گارسون کم نمیاره پس هر گارسون به سراغ یک میز میره و منو غذا ها رو تحویل میده و منتظر می مونه تا مشتری سفارش رو بده‌ (مثال برای synchronous) ، تا وقتی که تعداد گارسون ها زیاد باشه مشکلی پیش نمیاد ولی اگر گارسون ها کم باشن راه حل اینه :گارسون سراغ یک میز میره و منو رو تحویل میده و سراغ میز بعدی میره ، وقتی مشتری سفارشش رو انتخاب کرد گارسون رو خبر می کنه تا سفارش رو ثبت کنه‌ (مثال برای asynchronous)Talk is cheap show me the code!یک مثال از متد های synchronous :const fs = require(&#039;fs&#039;); 
const data = fs.readFileSync(&#039;/file.txt&#039;);وقتی متد readFileSync اجرا میشه process (روند) اپلیکیشن جاوا اسکریپت متوقف میشه تا فایل file.txt رو بخونه.یک مثال از متد های asynchronous :const fs = require(&#039;fs&#039;); 
function callback(err, data) {
      if (err) throw err;  
}
fs.readFile&#40;&#039;/file.md&#039;,  callback&#41;; ولی وقتی متد readFile اجرا میشه روند اپلیکیشن متوقف نمیشه و ادامه پیدا می کنه و زمانی که اطلاعات مورد نظر بدست اومد ، تابع callback صدا زده میشه و اطلاعات مورد نظر رو میشه از پارامتر data بدست آورد.نکته : تا جای ممکن از متد های asynchronous استفاده کنید تا پراسس مشغول نشه!!بجز callback ها روش های دیگه ای هم برای گرفتن مقدار از متد های asynchronous هست ....حالا بر می گردیم به بحث پرامیس ها :پرامیس معنی لغویش &quot;قول دادن&quot; هست ، در عمل یعنی پرامیس ها به شما قول میدن که یک جواب در ازای متدی که صدا زدید میده (چه اون جواب یک ارور باشه یا یک مقدار).دو راه برای گرفتن مقدار پرامیس ها : then, catchasync, await then, catchنکته : کلاس Promise یک کلاس گلوبال جاوااسکرپیته برای ساختن پرامیس هایک مثال برای این نوع :var p1 = new Promise((resolve, reject) =&gt; { 
    resolve(&#039;Success!&#039;); 
   // or // 
    reject(new Error(&amp;quotError!&amp;quot))
}); 
p1.then(value =&gt; { console.log(value); // Success! }) 
    .catch(reason =&gt; { console.error(reason); // Error! });اگر عملیات موفق بود .then اجرا میشه ولی اگر موفق نبود .catchasync, awaitیک مثال برای این نوع :var p1 = new Promise((resolve, reject) =&gt; {
      resolve(&#039;Success!&#039;);     
     // or //      
     reject(new Error(&amp;quotError!&amp;quot)) 
});

async function getValue() {
    const value = await p1;
    console.log(value);
}
getValue();وقتی تابع getValue صدا زده میشه پرامیس مقداری که باید رو میده (برای catch کردن ارور ها باید از try, catch استفاده کنید)توی این مقاله به صورت خیلی سطحی به این مبحث پرداختیم در مقاله های بعدی به صورت کامل تر توضیح میدم :)</description>
                <category>Alireza Taji</category>
                <author>Alireza Taji</author>
                <pubDate>Tue, 15 Dec 2020 23:35:47 +0330</pubDate>
            </item>
                    <item>
                <title>تفاوت var و let و const در جاوا اسکریپت</title>
                <link>https://virgool.io/WebDevelopers/%D8%AA%D9%81%D8%A7%D9%88%D8%AA-var-%D9%88-let-%D9%88-const-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-v5yseadyunen</link>
                <description>پیش نیاز ها : (این مقاله ها رو قبل خوندن این پست مطالعه کنین)اسکوپ ها در جاوا اسکریپتمتغیر ها رو می تونیم به چند صورت تعریف کنیم ، با استفاده از :varletconstWithout declaring (بدون دکلار کردن)ساختن متغیر بدون دکلار کردن :تنها استفاده این نوع تعریف کردن متغیر، استفاده در فانکشن هاست.این نوع متغیر ها تنها نوعی هستند که می تونن در function scope تعریف بشن و همینطور در global scope بشه ازشون استفاده کرد.function name(){
  x = 10;
}
name();
console.log(x);نکته : حتما باید تابع رو صدا بزنید تا متغیر تعریف بشهامااگر strict mode فعال باشه حتما باید متغیر ها رو با استفاده از var , const یا letاستفاده کنید و نمی تونین به این شکل تعریف کنینتفاوت var با let :اگر تفاوت این دو تا رو یاد بگیرین تفاوت const با var هم یاد می گیرید.Let و const فقط یک تفاوت دارنمتغیر هایی که با var تعریف میشن ویژگی هایی داره که let نداره :Hoisting :فقط و فقط این قابلیت رو var داره ،این ویژگی باعث میشه که متغیر هایی که دکلار میشن به بالا ترین خط اسکوپ خودشون برن ، به عبارتی شما می تونین یه متغیر رو تعریف کنین قبل از این که دکلارش کنینfunction run() {
console.log(foo); // undefined
var foo = &amp;quotFoo&amp;quot
console.log(foo); // Foo
}
run();اما حالا با let تست کنیم :function run() {
console.log(foo); // RefrenceError
let foo = &amp;quotFoo&amp;quot
console.log(foo); // Foo
}
run();Block scope :وقتی یک متغیر رو با var داخل block scope دکلار کنیم اون متغیر به صورت گلوبال ذخیره میشه ولی اگر با let دکلار بشه ، اون متغیر توی block scope ذخیره میشه{
var n1 = 5;
let n2 = 6;
}
console.log(n1) //5
console.log(n2) //RefrenceErrorGlobal object :وقتی ما میگیم یه متغیر گلوباله یعنی اون متغیر توی global execution contextذخیره شده و هر دوی متغیر های let , var توی گلوبال اسکوپ ، در global execution contextذخیره میشنولی Global object با global execution context فرق داره ، گلوبال آبجکت همون window یا globalThis (در commad line node)متغیر let به عنوان یه property داخل گلوبال آبجکت ذخیره نمیشه ولی var میشهvar a = 2;
console.log(window.a) // 2
let b = 3;
console.log(window.b) //undefinedRedeclaration :فقط var قابلیت redeclaration داره و letنداره (redeclaration به معنای مجددا دکلار کردن یه متغیره)var foo = &amp;quotfoo1&amp;quot
var foo = &amp;quotfoo2&amp;quot // OK
let bar = &amp;quotbar1&amp;quot
let bar = &amp;quotbar2&amp;quot // SyntaxErrorسوال : وقتی let هیچکدوم از قابلیت هایی که varداره رو نداره برای چی ازش استفاده کنیم؟این باعث میشه که مقدار کمتری از حافظه برنامه استفاده بشه و در مواقعی باعث جلوگیری از ساخت متغیر گلوبال اضافه میشه!خب گفتیم let و const فقط یک تفاوت دارن :Reassignable :متغیر هایی که با const ساخته میشن این ویژگی رو دارن که باعث میشه نتونیم مقدار اون ها رو عوض کنیمconst v = “a”;
v = “b”; // TypeErrorنکته : در object ها می تونیم مقدار property ها رو عوض کنیم ولی نمی تونیم object رو دوباره assignکنیمconst obj = {type : &#039;string&#039;}
obj = {type : &#039;number&#039;} // TypeError
obj.type = &#039;number&#039;; //OKبا آرزوی موفقیت :))-انتشارات توسعه دهندگان وب-</description>
                <category>Alireza Taji</category>
                <author>Alireza Taji</author>
                <pubDate>Mon, 29 Jun 2020 21:52:05 +0430</pubDate>
            </item>
                    <item>
                <title>چگونه توابع (functions) در جاوا اسکریپت کار می کنند؟؟</title>
                <link>https://virgool.io/WebDevelopers/%DA%86%DA%AF%D9%88%D9%86%D9%87-%D8%AA%D9%88%D8%A7%D8%A8%D8%B9-functions-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE-%DA%A9%D8%A7%D8%B1-%D9%85%DB%8C-%DA%A9%D9%86%D9%86%D8%AF-cwkjnwqwftky</link>
                <description>تا حالا به این فکر کردید وقتی یه متغیر رو صدا می زنید چه اتفاقاتی میفته تا اجرا بشه ؟همه فانکشن ها یه نوع متغیر حساب میشن.وقتی که برنامه اجرا میشه ، از اونجایی که جاوا اسکریپت asynchronous کار می کنه (در یه مقاله دیگه توضیح میدم)به همین دلیل اول از همه تمام متغیر ها رو به صورت undefined دکلار می کنه و همینطور اسم متغیر ها رو داخل global execution context ذخیره می کنه به همراه اون خطی که متغیر اونجا دکلار شده.function double(a) {
let myvar = a * 2;
return myvar;
}
let b = doube(2);
alert&#40;b&#41;;طبق مثال بالا برنامه اجرا میشه و توی خط اول یه متغیر به نام double داخل exection context ایجاد میشه که مقدارش undefined ئه و بعد برنامه تشخیص میده که این متغیر یک تابعه، پس تمام مقادیر داخل {} به این متغیر اختصاص می گیره ولی نه اجرا میشه نه خونده میشه فقط و فقط داخل exection context ذخیره میشه.برنامه اجرا میشه و جلو تر یه متغیر به نام b میرسه و دوباره با مقدار undefined ذخیره می کنه و وقتی جلو تر میره ، عملگر = رو می بینه که مقدار (double(2 رو به b نسبت داده و مقدار b در execution context تغییر می کنهخب برنامه وقتی که () می بینه متوجه میشه که این یه تابعه و داخل global exection context دنبال اسم double میگرده و اون رو پیدا می کنه و خطی که اون فانکشن اونجا قرار داره رو می گیره (خط یک برنامه) اجرای برنامه به خط یک میره و اونجا 2 به عنوان یک argument وارد فانکشن میشه.خب الان execution context عوض شدچون ما از گلوبال اسکوپ به لوکال اسکوپ رفتیم (پست مربوط به اسکوپ ها رو بخونید) و این بار متغیر ها در local execution context ذخیره میشن.متغیر myvar مثل بقیه متغیر ها ذخیره میشه.و برنامه به return میرسه ، وقتی return انجام میشه local execution context از بین میره (با متغیر هایی که داخلش ساخته شده)و اجرای برنامه دوباره به جایی که این فانکشن رو صدا زدیم بر می گرده و مقدار خارج شده از return به b تعلق می گیره.در نهایت (alert(b اجرا میشه.-انتشارات توسعه دهندگان وب-</description>
                <category>Alireza Taji</category>
                <author>Alireza Taji</author>
                <pubDate>Sat, 27 Jun 2020 11:58:52 +0430</pubDate>
            </item>
                    <item>
                <title>اسکوپ ها (scope) در جاوا اسکریپت</title>
                <link>https://virgool.io/WebDevelopers/%D8%A7%D8%B3%DA%A9%D9%88%D9%BE-%D9%87%D8%A7-scope-%D8%AF%D8%B1-%D8%AC%D8%A7%D9%88%D8%A7-%D8%A7%D8%B3%DA%A9%D8%B1%DB%8C%D9%BE%D8%AA-qlrdy6dgpjw7</link>
                <description>امروز می خوام scope  ها در جاوااسکریپت رو به زبان ساده توضیح بدم.معادل فارسی اسکوپ محدوده هست که مشخص می کنه هر متغیر در این زبان در چه محدوده ای قابل استفادست.یعنی نمیشه همه جای محیط برنامه به یه سری متغیر ها دسترسی پیدا کرد.خب ما در کل توی جاوااسکریپت چهار نوع اسکوپ :Global scopeFunction scope (local scope)Lexical scopeBlock scope (ES6)خب هر کدوم از این scope ها قواعد و ویژگی های مخصوص خودشون رو دارند، که به ترتیب توضیح میدمGlobal scopeاین اسکوپ تمام اسکوپ های برنامه رو در بر می گیره ، به عبارتی هر اسکوپی که شما می سازید زیر مجموعه این اسکوپ قرار می گیرهمیشه گفت شهری که شما داخلش زندگی می کنید یه گلوبال اسکوپه و تمام خونه ها و مغازه های داخل شهر سایر اسکوپ ها هستنددر برنامه نویسی سمت کلاینت object window اسکوپ گلوبال محسوب میشهنکته : object document گلوبال نیست و جزو زیر مجموعه window محسوب میشهBlock scopeما با ساختن هر کدوم از این موارد یه block scope  ساختیم:If, else statementBlock scope {}Labled scopeTry, catchاگر متغیری رو با const  یا let داخل بلاک اسکوپ تعریف (declare  کردن) کنیم، داخل گلوبال اسکوپ قابل استفاده نیستند !اما اگر متغیر ها رو تعریف نکنیم (مستقیما یه مقدار به متغیر بدیم بدون استفاده از var , let  یا const) یا اون رو با var  تعریف کنیم اون ها در گلوبال اسکوپ قابل استفاده هستند.مثل لوازم خونه شما می مونه همه مردم شهر نمی تونند از لوازمی که توی خونه شما هست استفاده کنن اما اعضای خونه می تونننکته : اگر strict mode  رو فعال کنید باید حتما متغیر ها رو تعریف کنید و نمی تونید مستقیم به اون ها یه مقدار بدینFunction scope (local scope)خب این اسکوپ یکی از تفاوت هایی که داره اینه که توی این اسکوپ متغیر var متغیر گلوبال محسوب نمیشه اما شما می تونید متغیر رو بیرون این اسکوپ تعریف کنید (توی محیط برنامه ، گلوبال اسکوپ) و داخل اسکوپ به اون یه مقدار بدین و از اون توی اسکوپ گلوبال استفاده کنیدیامی تونید متغیر رو تعریف نکنید ( از var , let , const استفاده نکنید) و مستقیما داخل تابع بهش یه مقدار بدیدنکته : برای استفاده از متغیر های function scope باید اول فانکشن رو صدا بزنید تا برنامه اون فانکشن رو اجرا کنه وگرنه هیچ متغیری وجود نخواهد داشتLexical scopeاین ویژگی باعث میشه که هر اسکوپی به تمام متغیر های اسکوپ های بالا تر از خودش (اسکوپ هایی که خود اسکوپ زیر مجموعه اون حساب میشن) دسترسی پیدا کنهمثال : هر عضو از خونه شما می تونه به امکاناتی که در شهر وجود داره دسترسی پیدا کنهبرای این که اسکوپ ها رو بفهمید باید خودتون کد های مختلف در اسکوپ های مختلف بنویسید و اسکوپ ها رو تست کنید!!امیدوارم این پست براتون مفید بوده باشه :))</description>
                <category>Alireza Taji</category>
                <author>Alireza Taji</author>
                <pubDate>Wed, 24 Jun 2020 20:38:26 +0430</pubDate>
            </item>
            </channel>
</rss>