<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>نوشته های Masoud Mirzaei</title>
        <link>https://virgool.io/feed/@mamsoudi</link>
        <description></description>
        <language>fa</language>
        <pubDate>2026-06-07 12:08:25</pubDate>
        <image>
            <url>https://files.virgool.io/upload/users/8004/avatar/avatar.png?height=120&amp;width=120</url>
            <title>Masoud Mirzaei</title>
            <link>https://virgool.io/@mamsoudi</link>
        </image>

                    <item>
                <title>دنباله دار کردن تابع ها در JavaScript یا Function Currying</title>
                <link>https://virgool.io/@mamsoudi/%D8%AF%D9%86%D8%A8%D8%A7%D9%84%D9%87-%D8%AF%D8%A7%D8%B1-%DA%A9%D8%B1%D8%AF%D9%86-%D8%AA%D8%A7%D8%A8%D8%B9-%D9%87%D8%A7-%D8%AF%D8%B1-javascript-%DB%8C%D8%A7-function-currying-sb4dstqz5vbu</link>
                <description>امروز وقتی داشتم برای یه مصاحبه کاری توی انگلیس تست فنی می دادم، یه سوالی خیلی مشغولم کرد و بعد از ۳۰ دقیقه و فقط وقتی ۲۹ ثانیه وقت به پایان مونده بود موفق شدم جواب درستش رو بنویسم.سوال میگه می خوایم یک تابع داشته باشیم که میشه به صورت دنباله دار صداش زد. تابع ما در واقع یک سری عدد رو به عنوان ورودی قبول می کنه و در نهایت قراره که جمع همه این اعداد رو به ما برگردونه.تست کیس ما همچین چیزیه: جمع اعداد ۱ تا ۵ که میشه ۱۵.add(1)(2)(3)(4)(5).result() // must return 15در نهایت کد ما به صورت بالا استفاده میشه، اما این امکان هم هست که ما رشته تابع add رو موقتا بندازیم توی یک متغیر و بعدا اگر دلمون خواست از طریق متد result نتیجه جمع شون رو چاپ کنیم. اینطوری:var sum1 = add(1)(2);
var sum2 = add(3)(4)(5);

var sumFinal = sum1.result() + sum2.result();قبل از اینکه از چه جوری انجامش رو بگم ببینید می تونید خودتون از پسش بر بیاین؟!  خوب حالا که خیلی کنجکاوی میریم سراغ روش انجامش! کاری که اینجا ما می خوایم انجام بدیم رو بهش می گن Function Currying.‍چیزی که خیلی واضحه اینه که ما هر باری که داریم متوالی add رو صدا می کنیم در واقع داریم مجددا همون تابع رو صدا می کنیم. تابعی که واسمون جمع زدن رو انجام میده درسته!؟اما ما داریم به صورت متمادی هم اینکارو می کنیم پس ما یه متغیری هم باید داشته باشیم که جمع زدن هامون رو توش انجام میدیم.بزارید بهتون نشون بدم منظورم چیه:// Define add function
function add(x) {
    // let&#039;s define a variable to keep the numbers we add
    let sum = x;
    
    // now we need to define a function that we return every time after first invokes
    function resultFn(y) {
        // Add the numbers we take after the first time to the one we first kept!
        sum += y;
        // And return resultFn to make it possible we call it afterwards
        return resultFn;
    }
    
    // We haven&#039;t been returning the results! so let&#039;s do that
    // Lets add a method to the resultFn we&#039;ve developed to return the current sum
    // whenever it&#039;s invoked
    resultFn.result = function () {
        return sum;
    }
    return resultFn;
}اما توضیحاتش:ما یه تابع داریم به اسم add. توی این تابع فقط و فقط دفعه اولی که صدا زده میشه ما اولین عددی که میگیریم رو میندازیم توی یه متغیری به اسم sum. این sum رو بعدا استفاده می کنیم تا عدد های بعدی رو توش جمع بزنیم. حالا میایم یه تابع جدید تعریف می کنیم به اسم resultFn که اونم توی خود add هست و قراره از این به بعد اونو برگردونیم و صدا بزنیم و دیگه خود add رو کاری نداریم. چرا؟‌ چون می خوایم بتونیم add رو اینطوری صدا بزنیم:add(1)(2)...(n)توی resultFn ما میایم عدد جدیدمون رو که حالا با y نشونش میدیم به اون sum قبلی اضافه می کنیم! باید دقت کنیم که sum ما از اون بار اول دست نخورده مگر اینکه توی resultFn تغییرش بدیم!پس در واقع از بار دوم به بعد هر باری که ما یه پرانتز اضافه می کنیم داریم resultFn رو صدا می کنیم نه add. و در نهایت از اونجایی که چیزی که برگشته resultFn هست، ما یک متد بهش اضافه کردیم که sum ما که توی closure تابع  add ثابت مونده رو بهمون برمیگردونه.حالا آزمایشش کنیم:add(1)(2)(3)(4)(5).result() // returns 15var sum1 = add(1)(2); // returns resultFn
var sum2 = add(3)(4)(5);  // returns resultFn
var sumFinal = sum1.result() + sum2.result(); // returns 15حالا یه خورده فکرتونو به کار بندازین ببینین می تونید همینکارو واسه ضرب هم انجام بدین؟!در مورد function currying بخونید. چیزی که خیلی با method chaining متفاوته ولی به درد بخور. جاوا اسکریپت دنیای جالبی داره و اینم امروز چلنج جالبی بود که بهش برخوردم.دنبال چیزای خفن باشین و همیشه کنجکاو باشین ✌?</description>
                <category>Masoud Mirzaei</category>
                <author>Masoud Mirzaei</author>
                <pubDate>Thu, 28 Mar 2019 03:37:54 +0430</pubDate>
            </item>
                    <item>
                <title>Thread ها در Node 10.5.0: یک شروع عملی</title>
                <link>https://virgool.io/JavaScript8/getting-started-with-nodejs-threads-v9djkgpp6rud</link>
                <description>چند روز پیش ورژن ۱۰.۵.۰ Node.js منتشر شد و یکی از قابلیت های اصلی که در اون اضافه شده بود پشتیبانی آزمایشی از Thread ها بود. این موضوع زمانی جذاب میشه که در مورد زبانی صحبت می کنیم که همیشه به خاطر عدم نیازش به Thread ها و Async I/O محبوب و خارق العاده ش به خودش غرّه بوده.ولی چرا اصلا Node باید به Thread ها نیاز داشته باشه؟جواب ساده و کوتاه اینه که: برای بهتر شدن تو زمینه هایی که Node قبلا تو گذشته در اونها رنج کشیده یا پردازش هایی که نیاز به استفاده های سنگین از CPU دارن. به خاطر همین موضوع هست که Node.js توی زمینه هایی مثل AI، یادگیری ماشین یا داده پردازی و زمینه های اینچنینی خیلی قوی نیست. تلاش های زیادی برای بهبود این موضوع صورت گرفته ولی هنوز نمی تونیم به خوبی زمانی از Node استفاده کنیم که میکروسرویس ها رو deploy می کنیم.پس در این مقاله تلاش می کنیم که مستندات فنی که توسط PR اولیه و مستندات رسمی توضیح داده شده اند رو به صورت عملی تر و به کمک یک سری مثال های ساده توضیح بدیم. این احتمالا به شما کمک می کنه که از این قابلیت جدید استفاده کنید.اما چجوری از ماژول جدید Thread ها استفاده کنیم؟برای شروع با require کردن ماژولی به اسم &quot;worker_threads&quot; شروع می کنیم.این موضوع رو به خاطر داشته باشین که تمام کد ها تنها زمانی کار می کنن که از flag مخصوص --experimental-worker موقع اجرای اسکریپت ها استفاده کنید وگرنه ماژول نامبرده پیدا نمیشه.توجه کنین که flag به worker اشاره می کنه و نه thread ها، که دقیقا به همین شکل هم در سرتاسر مستندات بهش اشاره میشه: worker threads یا به صورت خلاصه تر workers.اگر قبلا از multi-processing استفاده کردین شباهت های زیادی باهاش پیدا می کنین وگرنه نگران نباشید و تا هر مقدار که بشه توضیح میدم.خوب با Thread اصن چیکار میشه کرد؟Worker Thread ها همونطور که قبلا گفتم برای کارهایی که CPU زیادی مصرف می کنن ساخته شدن و استفاده ازشون برای I/O فقط هدررفت منابع به حساب میاد چون که بر اساس مستندات رسمی، مکانیزم داخلی Node برای async I/O خیلی بیشتر از worker thread ها بهینه است، پس خودتون رو اذیت نکنین.بزارین با یه مثال ساده شروع کنیم که توش Worker میسازیم و ازش استفاده می کنیم.مثال اول: https://gist.github.com/deleteman/aa19d01fee124239ebf8fd2f5f6134b6 مثال بالا خروج ساده ای داره که در اون خط هایی شمارنه ها یا افزایشی رو نشون میدن که مقادیرشون با سرعت های متفاوت افزایش پیدا می کنهخروجی کد بالابزارین جزییات بیشتری بگیم:کد داخل IF دو worker thread میسازه و کدی که برای اون ها استفاده شده از یک فایل گرفته میشه چون پارامتر __filename رو بهش تحویل دادیم. Worker ها فعلا نیاز به مسیر های کامل به فایل ها دارن و با مسیر های وابسته (Relative Paths) سازگاری ندارن برای همین این پارامتر بهش داده شده. هر دو worker به عنوان مقادیری global در آرگومان دوم به عنوان workerData پاس داده شدن. دسترسی به این مقدار می تونه به عنوان یک ثابت با اسمی یکسان وجود داشته باشه (ببینید که چطوری ثابت، توی خط اول فایل ساخته شده و بعدا در خط آخر از اون استفاده میشه.)این مثال یکی از ساده ترین هایی که می تونید با استفاده از این ماژول ازش بهره بگیرید،‌ ولی به نظر جالب میاد نه؟ بزارین یه نگاهی به مثال دیگه بندازیم.مثال دوم، واقعا یه کاری بکنیم.بیاین تلاش کنیم واقعا وقتی داریم یه سری کارای async توی thread اصلی می کنیم یک سری محاسبات «سنگین» هم انجام بدیم.  https://gist.github.com/deleteman/c31a9704f9cbe3b15c45bb439a4c0da2 این بار ولی، داریم به صفحه اصلی گوگل درخواست می زنیم و همزمان یک آرایه شامل ۱ میلیون عدد که اتفاقی ساخته شده اند رو مرتب می کنیم. این کار چند ثانیه طول می کشه، پس مهمه که نشون بدیم این ماژول چقدر خوب کار می کنه. همچنین می خوایم زمانی که worker thread برای اجرای مرتب سازی میگیره رو اندازه گیری کنیم و در کنارم مقادیر مرتب شده به thread اصلی بفرستیم جایی که نتیجه رو نشون میدیم.نتیجه مثال دوماصلی ترین خروجی این مثال ارتباط بین thread هاست. Worker ها می تونن پیام هایی رو از طریق متد on به thread اصلی بفرستن. Event هایی که می تونیم بهشون listen کنیم رو میشه توی کد دید. event به اسم message زمانی رخ میده که پیامی از یک thread با استفاده از متد parentPort.postMessage بفرستیم. همچنین میشه پیامی رو به کد thread با استفاده از همین متد،‌ روی worker فرستاد و با استفاده از parentPort دریافتش کرد.اگه کنجکاو شدین، کدی ماژول helper ـی که من استفاده می کنم اینجاست، اگرچه چیز خاصی در موردش وجود نداره.بیاین نگاهی بندازیم به یه مثال مشابه ولی با کد تمیز تر که یک ایده نهایی از اینکه چجوری باید به کد های worker thread ها ساختار داد میده.مثال ۳: همه چی کنار همبه عنوان یک مثال نهایی می خوام به همون عملکرد بپردازیم ولی نشون بدیم چطوری می تونیم یک نسخه که قابل نگهداریه با تمیز کردنش ازش بسازیم. https://gist.github.com/deleteman/8e0c6d51c6875e1fc0e147c31e1d6897  وکدمربوطبهthreadهامیتونهتوییهفایلدیگهباشه،مثل:  https://gist.github.com/deleteman/df2119b1d386d3de3f2d86bad12ff32e با نگاه به جزییات می فهمیم که:Thread اصلی و worker thread ها حالا کد خودشون رو اینبار در فایل های متفاوت دارن که بهتر قابلیت نگه داری و توسعه داره.تابع startWorker حالا یک شاخه جدید از worker بر می گردونه که اجازه میده بعدا اگر نیاز بود بهش پیام بفرستید.اگر کد های thread اصلی واقعا همون thread اصلی باشن دیگه نیازی به نگرانی نیست (ما شرط IF رو حذف کردیم.)میشه تو کد های worker دید که چه طوری میشه پیام ها رو از thread اصلی گرفت که اجازه میده ارتباط دو طرفه async بوجود بیاریم.خوب واسه این مقاله دیگه کافیه، امیدوارم به اندازه کافی مقاله رو متوجه شده باشین که بهتون کمک کنه با این ماژول جدید شروع به کار کنید. ولی یادتون باشه که:این ماژول هنوز شدیدا تو حالت آزمایش قرار داره و چیزایی که اینجا توضیح داده شده ممکنه توی انتشار های آینده تغییر کنه.نظرات PR و مستندات رو بخونید،‌چرا که اطلاعات بیشتری در این باره اونجا موجوده و من فقط روی قدم های پایه ای برای شروع به کار تمرکز کردم. ازش لذت ببرین! یه خورده باش ور برین، باگ هاش رو گزارش بدین و واسه بهتر شدنش پیشنهاد بدین چرا که این تازه شروعشه!تا مقاله بعدی!</description>
                <category>Masoud Mirzaei</category>
                <author>Masoud Mirzaei</author>
                <pubDate>Tue, 11 Sep 2018 00:40:43 +0430</pubDate>
            </item>
            </channel>
</rss>