https://www.linkedin.com/posts/mohammad-esfandiari-ab069322a_%D8%A7%D8%B3%D8%AA%D8%A7%D8%B1%D8%AA%D8%A7%D9%BE-%D9%85%D9%81%DB%8C%D8%AF-backend-developer-%D8%AC%D8%B0%D8%A8-%D9%85%DB%8C%DA%A9%D9%86%D8%AF-activity-7145778735194009600-UVNL?utm_source=share&utm_medium=member_andro
#Work
#Work
Linkedin
Mohammad Esfandiari on LinkedIn: استارتاپ مفید Backend developer جذب میکند.
مهارت های فنی:
مسلط به:…
مهارت های فنی:
مسلط به:…
استارتاپ مفید Backend developer جذب میکند.
مهارت های فنی:
مسلط به: Express js
مسلط به: Node js
مسلط به: Nest js
مسلط به : Graph QL
مسلط به : Mongo DB
مسلط…
مهارت های فنی:
مسلط به: Express js
مسلط به: Node js
مسلط به: Nest js
مسلط به : Graph QL
مسلط به : Mongo DB
مسلط…
Node Master
خب first class function یعنی چی؟ به این موضوع هست که شما میتونید با function ها مثل بقیه object ها رفتار کنید. یعنی در متغیر ذخیرشون کنید یک لیستی از function ها داشته باشید و یا حتی در runtime فانکشن جدید بسازید و return کنید. این موضوع خیلی نکته قوی هست…
خب هنوز یک قدم میخوایم پا رو فراتر بزاریم و class رو در runtime بسازیم. اول این که در #Javanoscript کلاس ها در حقیقت همون فانکشن ها هستن و صرفا کلمه class یک syntactic sugar روی نسخه ES5 هست. کلمه class در آپدیت معروف ES6 به #Javanoscript اضافه شد.
یعنی این دوتا باهم برابر هستند.
قدیما وقتی میخواستن کلاس بسازن از syntax به شکل User2 استفاده میکردن. اسم این مدل ES5 function constructors ولی چون شکل قشنگی نداشت class syntax رو اضاف کردن. هردو اینا دقیق برابر هستن یعنی در اصل class syntax اون پشت تبدیل میشه به مدل User2 اینطور تصور کنید.
اونجا که کامنت کردم خیلی میتونست ساده تر باشه. دیدم فرصت خوبی هست که بحثش رو بیارم وسط. بحث خیلی مهمی هست و یکی از خاصیت های زبان های dynamic type هست. فکر کنید راجع بهش کامنت بزارید در ادامه درموردش صحبت خواهیم کرد.
میریم سر اصل مطلب. اگر دقت کنید قدیما وقتی میخواستن کلاس بسازن از function استفاده میکردن ( منطقی یا غیرمنطقی بودن این موضوع یک بحث دیگس که کاری نداریم) پست قبلی یاد گرفتیم که function ها در حقیقت first class هستن و میتونیم هرکاری باهاشون کنیم! آفرین دقیقه نکته داستان همینه. به این دلیل که کلاس ها تبدیل میشن به ES5 function constructors اون پشت پس تمامی کارایی که قبل میتونستیم کنیم مجازه. بریم برای مثال.
مثال یکم فرانتی هست. ما کلاس رو در runtime ایجاد کردیم و براش private attr ست کردیم و اگر این کد رو اجرا کنید میبینید هم getter به درستی کار میکنه و هم شما مستقیم دسترسی به color ندارید. نکته جالب اینه دوباره برا مثال خوردیم به pattern بالا که گفتم. بهش فکر کنید.
یک نکته ای که وجود داره اینه که این ها anonymous class هستن و اسم ندارند. کد زیر رو اجرا کنید
حالا اگر بخوایم name رو به صورت HardCode بزنیم داخل btnFactory قشنگ در نمیاد چون همه کلاس ها یک اسم خواهند داشت. اگر anonymous هم باشیم ساعت های سختی رو برای debug خواهیم داشت.
تا همینجا برای این پست کافیه پست بعدی یکم عمیق تر میشیم در metaprograming.
یعنی این دوتا باهم برابر هستند.
// Syntactic Sugar
class User {
constructor(name, last_name) {
this.name = name;
this.last_name = last_name;
}
printFullName() {
console.log(this.name + " " + this.last_name);
}
}
function User2(name, last_name) {
this.name = name;
this.last_name = last_name;
}
User2.prototype.printFullName = function () {
console.log(this.name + " " + this.last_name);
};
// Think about this part. 🤔
const users = [new User("iman", "hpr"), new User2("iman", "hpr")];
users.forEach((user) => console.log(user.printFullName()));
قدیما وقتی میخواستن کلاس بسازن از syntax به شکل User2 استفاده میکردن. اسم این مدل ES5 function constructors ولی چون شکل قشنگی نداشت class syntax رو اضاف کردن. هردو اینا دقیق برابر هستن یعنی در اصل class syntax اون پشت تبدیل میشه به مدل User2 اینطور تصور کنید.
اونجا که کامنت کردم خیلی میتونست ساده تر باشه. دیدم فرصت خوبی هست که بحثش رو بیارم وسط. بحث خیلی مهمی هست و یکی از خاصیت های زبان های dynamic type هست. فکر کنید راجع بهش کامنت بزارید در ادامه درموردش صحبت خواهیم کرد.
میریم سر اصل مطلب. اگر دقت کنید قدیما وقتی میخواستن کلاس بسازن از function استفاده میکردن ( منطقی یا غیرمنطقی بودن این موضوع یک بحث دیگس که کاری نداریم) پست قبلی یاد گرفتیم که function ها در حقیقت first class هستن و میتونیم هرکاری باهاشون کنیم! آفرین دقیقه نکته داستان همینه. به این دلیل که کلاس ها تبدیل میشن به ES5 function constructors اون پشت پس تمامی کارایی که قبل میتونستیم کنیم مجازه. بریم برای مثال.
function buttonFactory(color) {
return class {
#color = color;
get color() {
return this.#color;
}
show() {
console.log("Button is " + this.#color);
}
};
}
const BlueBtnCls = buttonFactory("blue");
const RedBtnCls = buttonFactory("red");
const blueBtn = new BlueBtnCls();
const redBtn = new RedBtnCls();
// Here we go agin 😉. Think about it one more 🤔
const btns = [blueBtn, redBtn].forEach((btn) => btn.show());مثال یکم فرانتی هست. ما کلاس رو در runtime ایجاد کردیم و براش private attr ست کردیم و اگر این کد رو اجرا کنید میبینید هم getter به درستی کار میکنه و هم شما مستقیم دسترسی به color ندارید. نکته جالب اینه دوباره برا مثال خوردیم به pattern بالا که گفتم. بهش فکر کنید.
یک نکته ای که وجود داره اینه که این ها anonymous class هستن و اسم ندارند. کد زیر رو اجرا کنید
const BlueBtnCls = buttonFactory("blue");
console.log(BlueBtnCls) // out : [class (anonymous)]
console.log(BlueBtnCls.name)حالا اگر بخوایم name رو به صورت HardCode بزنیم داخل btnFactory قشنگ در نمیاد چون همه کلاس ها یک اسم خواهند داشت. اگر anonymous هم باشیم ساعت های سختی رو برای debug خواهیم داشت.
تا همینجا برای این پست کافیه پست بعدی یکم عمیق تر میشیم در metaprograming.
👍13
Node Master
Hint for question :) 🦆
جواب این سوال Duck Typing بود که در آینده حتما راجع بهش صحبت میکنیم.
پست بعدی ادامه همین پست رو کامل میکنیم👍
پست بعدی ادامه همین پست رو کامل میکنیم👍
👍3
Node Master
خب هنوز یک قدم میخوایم پا رو فراتر بزاریم و class رو در runtime بسازیم. اول این که در #Javanoscript کلاس ها در حقیقت همون فانکشن ها هستن و صرفا کلمه class یک syntactic sugar روی نسخه ES5 هست. کلمه class در آپدیت معروف ES6 به #Javanoscript اضافه شد. یعنی این دوتا…
در پست قبل یاد گرفتیم که چطور یک کلاس در Runtime بسازیم. و موضوعی باز موند که چطور میتونیم اسم کلاس ها هم در Runtime تغییر بدیم. برای این کار نیاز به یک تکنیک دیگه که در #Metaprogramming خیلی پر استفاده هست باید استفاده کنیم. به اسم Reflection. این تکنیک در اکثر زبان ها به طریقی وجود داره. golang و java دقیقا lib های خیلی قوی مربوط به این تکنیک دارند. متاسفانه Reflection در #Javanoscript خیلی محدود هست و قدرت زبان های دیگ رو نداره ولی اینجا کاربرد داره.
- حالا Reflection چیست؟ در حقیقت Reflection به معنی توضیح دادن یک کد با استفاده از یک کد دیگه.
زبان Lisp یک زبان قدیمی هست و استفاده خاصی این روزا نداره ولی یک فلسفه خیلی معروف به دنیای برنامه نویسی معرفی کرد.
- "Code Is Data"
بخوایم توضیح بالا رو کامل تر و ساده تر کنیم یعنی با کد برنامه مثل دیتا معمولی رفتار کنیم! این هم بگم اگر یکم درکش سخت هست براتون کاملا منطقیه. این نوع تفکر نیاز به تمرین زیادی داره پس زیاد سخت نگیرید.
راجع به Lisp و این موضوع در آینده بیشتر صحبت میکنیم.
حالا کد بالا رو در نظر بگیرید. و به مثال زیر دقت کنید.
برای این که کد بالا رو توضیح بدم اول این نکته رو باید در نظر داشته باشید که هر function یک attr به اسم name داره که اسم فانکشن هست. اگر راهی پیدا کنیم که بتونیم این رو در runtime تغییر بدیم پس مشکلی نخواهیم داشت.
در #Javanoscript دو namespace برای کمک به ما در Reflection وجود دارد.
- Reflect
- Object
در این name space ها یک سری static method برای کمک هستن که در کد بالا نمونه ای میبینید که ما اومدیم یک cls رو ساختیم و reference اون رو نگهداری میکنیم. بعد با استفاده از اون ref و کمک reflection در runtime به راحتی name رو به چیزی که میخوایم تغییر میدیم. بعد ref رو return میکنیم.
نکته در مورد مثال:
- خیلی خلاصه گویی شده به دلیلی که مطلب طولانی نشه.
- اینجا هدف فقط اشاره و لمس این موضوع هست در آینده بیشتر صحبت خواهیم کرد.
- حالا Reflection چیست؟ در حقیقت Reflection به معنی توضیح دادن یک کد با استفاده از یک کد دیگه.
زبان Lisp یک زبان قدیمی هست و استفاده خاصی این روزا نداره ولی یک فلسفه خیلی معروف به دنیای برنامه نویسی معرفی کرد.
- "Code Is Data"
بخوایم توضیح بالا رو کامل تر و ساده تر کنیم یعنی با کد برنامه مثل دیتا معمولی رفتار کنیم! این هم بگم اگر یکم درکش سخت هست براتون کاملا منطقیه. این نوع تفکر نیاز به تمرین زیادی داره پس زیاد سخت نگیرید.
راجع به Lisp و این موضوع در آینده بیشتر صحبت میکنیم.
حالا کد بالا رو در نظر بگیرید. و به مثال زیر دقت کنید.
function buttonFactory(color) {
const cls = class {
#color = color;
get color() {
return this.#color;
}
show() {
console.log("Button is " + this.#color);
}
};
Reflect.defineProperty(cls, "name", {
writable: false,
value: color[0].toUpperCase() + color.slice(1) + "Btn",
});
return cls;
}برای این که کد بالا رو توضیح بدم اول این نکته رو باید در نظر داشته باشید که هر function یک attr به اسم name داره که اسم فانکشن هست. اگر راهی پیدا کنیم که بتونیم این رو در runtime تغییر بدیم پس مشکلی نخواهیم داشت.
function SayMyName() {}
console.log(SayMyName.name);در #Javanoscript دو namespace برای کمک به ما در Reflection وجود دارد.
- Reflect
- Object
در این name space ها یک سری static method برای کمک هستن که در کد بالا نمونه ای میبینید که ما اومدیم یک cls رو ساختیم و reference اون رو نگهداری میکنیم. بعد با استفاده از اون ref و کمک reflection در runtime به راحتی name رو به چیزی که میخوایم تغییر میدیم. بعد ref رو return میکنیم.
نکته در مورد مثال:
- خیلی خلاصه گویی شده به دلیلی که مطلب طولانی نشه.
- اینجا هدف فقط اشاره و لمس این موضوع هست در آینده بیشتر صحبت خواهیم کرد.
👍14
سلام و ارادت دوستان.
نکته امروز رو با یک سوال شروع میکنیم. بنظرتون چرا باید از Object.freeze بیشتر استفاده کنیم؟
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
نکته امروز رو با یک سوال شروع میکنیم. بنظرتون چرا باید از Object.freeze بیشتر استفاده کنیم؟
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
MDN Web Docs
Object.freeze() - JavaScript | MDN
The Object.freeze() static method freezes an object. Freezing an object prevents extensions and makes existing properties non-writable and non-configurable. A frozen object can no longer be changed: new properties cannot be added, existing properties cannot…
نسخه 20.11 LTS برای #NodeJS منتشر شد.
- بهینه سازی های خیلی زیاد در fs module اتفاق افتاده.
- اضافه کردن معادل __dirname و __filename که در CJS وجود داشت در ماژول های ESM
قدیما برای بدست اوردن filename و dirname باید با استفاده از import.meta.url اینکار میکردی که زیاد جالب نبود.
به عنوان مثال معادل import.meta.dirname قبل از این ورژن این شکل بود.
#NodeJS
#Update
- بهینه سازی های خیلی زیاد در fs module اتفاق افتاده.
- اضافه کردن معادل __dirname و __filename که در CJS وجود داشت در ماژول های ESM
import.meta.dirname // ESM
__dirname //CJS
import.meta.filename // ESM
__filename //CJS
قدیما برای بدست اوردن filename و dirname باید با استفاده از import.meta.url اینکار میکردی که زیاد جالب نبود.
به عنوان مثال معادل import.meta.dirname قبل از این ورژن این شکل بود.
import path from "node:path";
import url from "node:url";
const __dirname = path.dirname(url.fileURLToPath(import.meta.url)); // Before 20.11 LTS
// import.meta.dirname 20.11 LTS
const __filename = url.fileURLToPath(import.meta.url); // Before 20.11 LTS
// import.meta.filename 20.11 LTS
console.log(__filename);
console.log(__dirname);
#NodeJS
#Update
👍17
Node Master
سلام و ارادت دوستان. نکته امروز رو با یک سوال شروع میکنیم. بنظرتون چرا باید از Object.freeze بیشتر استفاده کنیم؟ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
این شاید یک static method کوچیک باشه ولی فلسفه پشتش نیاز به توضیح زیادی داره. به این مثال توجه کنید.
خیلی ساده هست با کمک Object.freeze من object مورد نظر رو به readonly تبدیل میکنم و شما نمیتونید این رو عوض کنید. ساده بنظر میاد اما اصلا چرا به همچین چیزی نیاز داریم؟ در کل اکوسیستم این رفتار رو به شکل ها و سطوح مختلف میبینید که پایین چنتا مثال زدم.
- در زبان #RustLang تمامی variable ها به صورت پیشفرض immutable هستند و شما باید به صراحت اعلام کنید که یک variable mutable هست.
- یکی از اصول زبان های functional تاکید بر immutable بودن object ها دارد.
- یک best practise وجود داره که میگه همیشه از const استفاده کنید مگر واقعا نیاز داشته باشید که این کار رو نکنید.
پشت تمامی این داستان ها میرسیم به یک جمله معروف که میگه "mutability is evil". تمام نکات بالا برمیگرده به همین جمله معروف اما سوال پیش میاد که چرا برای این موضوع اینقدر پیچدگی داریم؟ اصلا چرا؟
جواب این هست که immutable بودن object ها به ما کمک میکند تا side effect ها را به حداقل برسونیم. این نکته به این معنی نیست که side effect ها چیز بدی هست. نکته این هست که بدون side effect کلا نوشتن برنامه مفید غیرممکنه ولی اگر کمترش کنیم بهمون میتونه کمک کنه. حالا چنتا سوال خیلی مهم پیش میاد برامون.
- داستان side effect چی هست و چرا باید کمترش کنیم؟
- داستان immutable و mutable چیست؟
- چطور کمتر کردن side effect بهمون کمک میکنه؟
- کجاها side effect میتونه فاجعه بار باشه؟
- ربط mutability با side effect چیه؟
جواب دادن به هرکدوم از این سوالات وقت زیادی میخواد که باهم این ها رو در آینده نگاه میکنیم. این نکته رو یادتون باشه که دونستن این نکات خیلی میتونه بهمون کمک کنه که software engineer بهتری باشیم. از چیز های کوچیک سطحی رد نشیم و سعی کنیم چشمامون رو عادت بدیم که دقیق نگاه کنیم.
#Tip
const channel = Object.freeze({ name: "NodeMaster" });
channel.name = "IDK"; // TypeErrorخیلی ساده هست با کمک Object.freeze من object مورد نظر رو به readonly تبدیل میکنم و شما نمیتونید این رو عوض کنید. ساده بنظر میاد اما اصلا چرا به همچین چیزی نیاز داریم؟ در کل اکوسیستم این رفتار رو به شکل ها و سطوح مختلف میبینید که پایین چنتا مثال زدم.
- در زبان #RustLang تمامی variable ها به صورت پیشفرض immutable هستند و شما باید به صراحت اعلام کنید که یک variable mutable هست.
- یکی از اصول زبان های functional تاکید بر immutable بودن object ها دارد.
- یک best practise وجود داره که میگه همیشه از const استفاده کنید مگر واقعا نیاز داشته باشید که این کار رو نکنید.
پشت تمامی این داستان ها میرسیم به یک جمله معروف که میگه "mutability is evil". تمام نکات بالا برمیگرده به همین جمله معروف اما سوال پیش میاد که چرا برای این موضوع اینقدر پیچدگی داریم؟ اصلا چرا؟
جواب این هست که immutable بودن object ها به ما کمک میکند تا side effect ها را به حداقل برسونیم. این نکته به این معنی نیست که side effect ها چیز بدی هست. نکته این هست که بدون side effect کلا نوشتن برنامه مفید غیرممکنه ولی اگر کمترش کنیم بهمون میتونه کمک کنه. حالا چنتا سوال خیلی مهم پیش میاد برامون.
- داستان side effect چی هست و چرا باید کمترش کنیم؟
- داستان immutable و mutable چیست؟
- چطور کمتر کردن side effect بهمون کمک میکنه؟
- کجاها side effect میتونه فاجعه بار باشه؟
- ربط mutability با side effect چیه؟
جواب دادن به هرکدوم از این سوالات وقت زیادی میخواد که باهم این ها رو در آینده نگاه میکنیم. این نکته رو یادتون باشه که دونستن این نکات خیلی میتونه بهمون کمک کنه که software engineer بهتری باشیم. از چیز های کوچیک سطحی رد نشیم و سعی کنیم چشمامون رو عادت بدیم که دقیق نگاه کنیم.
#Tip
👍14
Node Master
بزارید ادامه این بحث رو با توضیح کوتاهی از Process شروع کنیم. Process چیست؟ در حقیقت Process یک instace از یک برنامه در حال اجرا که معمولا روی RAM جا دارد. برنامه در حال اجرا روی سیستم عامل برای اجرا دستورات خود نیاز به منابعی از قبیل حافظه و cpu time دارد.…
امروز در گروه کانال بچه ها راجع به concurrency در #NodeJS یکم صحبت کردن من هم از این فرصت استفاده میکنم توضیحاتی بدم.
این جمله رو زیاد شنیدیم #NodeJS به صورت Single thread و async هست. این جمله یک نقص بزرگ داره و آدم رو به اشتباه میندازه. کامل تر این شکل میشه که بخش آخر رو بگیم #NodeJS در حقیقت Async I/O است. این I/O خیلی مهم هست. در برنامه نویسی هر task به دو دسته تقسیم میشه که میشه به چشم bottleneck نگاه کرد
- کار های I/O base (Input/Output) : منظور از این مدل کار ها گرفتن یا فرستادن اطلاعات به کلاینت مثل فرستادن http request دریافت http response یا همون network یا کار با file system و ...
- کار های CPU Intensive ( به صورت عادی باعث بلاک شدن event loop و یا کند شدن میشوند. ) : تبدیل فرمت عکس از jpg به png یا پرداش ویدیو یا tls termintion یا فرایند فشرده سازی http response تولید شده با استفاده از gzip. حتی for loop ساده !
ما concurrency مدل های مختلفی داریم که مثال
- Async IO
- multithreading
- multiprocessing
برای کار های از نوع IO بهترین مدل asyic i/o هست برای کار های cpu intesive دو مدل دیگ. مدل hybrid و ترکیبی اینها هم وجود داره که خیلی پیشرفته هستن و زیاد هم استفاده میشن. نمونه خیلی معروف مدل Hybrid که انقلاب بود و هست Nginx.
در بهترین حالت این هست که ما با #NodeJS کار CPU intensive انجام ندیم اما گاهی مجبوریم. حالا با استفاده از "node:child_process" و "node:worker_thread" میتونیم کمک خیلی زیادی به Node کنیم.
در مثال پایین با یک کار فیک CPU intensive به طور کل event loop رو بلاک میکنیم و بعد با worker thread برنامه رو سریع تر میکنیم. اول با تعریف یک کار cpu intensive شروع میکنیم
کد خیلی ساده هست با for تا 500.000 هزار میشماریم لاگ میگیریم. این به این معنی هست هربار در برنامه node خودتون دارید loop میزنید در حقیقت دارید به Node خیانت میکنین. به هیچ عنوان روی آرایه های بزرگ از متد های foreach, map ,every و ... استفاده نکنید.
بعد با http ماژول یک وب سرور ساده مینویسیم
روی پورت 3000 یک وب سرور داریم که بعد از انجام دادن کار cpuBlockingTask یک 200 با متن Done میفرسته. سرور رو ران کنید.
یک ابزار هست به اسم AutoCannon برای Load test های ساده استفاده میشه. حجم زیادی از ریکوست رو میفرستیم سمت سرور.
https://www.npmjs.com/package/autocannon
توپ رو شلیک میکنیم سمت سرور با حالت پیشفرض که داخل داکیومنت نوشته البته یک flag هم ست میکنیم تا درخواست های موفق رو بشماریم.
نتیجه در سیستم من : فقط ۳ ریکوست موفق با تنظیمات پیشفرض
بخش اول ❇️
ادامه پست بعدی ❇️
این جمله رو زیاد شنیدیم #NodeJS به صورت Single thread و async هست. این جمله یک نقص بزرگ داره و آدم رو به اشتباه میندازه. کامل تر این شکل میشه که بخش آخر رو بگیم #NodeJS در حقیقت Async I/O است. این I/O خیلی مهم هست. در برنامه نویسی هر task به دو دسته تقسیم میشه که میشه به چشم bottleneck نگاه کرد
- کار های I/O base (Input/Output) : منظور از این مدل کار ها گرفتن یا فرستادن اطلاعات به کلاینت مثل فرستادن http request دریافت http response یا همون network یا کار با file system و ...
- کار های CPU Intensive ( به صورت عادی باعث بلاک شدن event loop و یا کند شدن میشوند. ) : تبدیل فرمت عکس از jpg به png یا پرداش ویدیو یا tls termintion یا فرایند فشرده سازی http response تولید شده با استفاده از gzip. حتی for loop ساده !
ما concurrency مدل های مختلفی داریم که مثال
- Async IO
- multithreading
- multiprocessing
برای کار های از نوع IO بهترین مدل asyic i/o هست برای کار های cpu intesive دو مدل دیگ. مدل hybrid و ترکیبی اینها هم وجود داره که خیلی پیشرفته هستن و زیاد هم استفاده میشن. نمونه خیلی معروف مدل Hybrid که انقلاب بود و هست Nginx.
در بهترین حالت این هست که ما با #NodeJS کار CPU intensive انجام ندیم اما گاهی مجبوریم. حالا با استفاده از "node:child_process" و "node:worker_thread" میتونیم کمک خیلی زیادی به Node کنیم.
در مثال پایین با یک کار فیک CPU intensive به طور کل event loop رو بلاک میکنیم و بعد با worker thread برنامه رو سریع تر میکنیم. اول با تعریف یک کار cpu intensive شروع میکنیم
function cpuBlockingTask() {
for (let i = 0; i < 5e5; ++i) console.log(i);
}کد خیلی ساده هست با for تا 500.000 هزار میشماریم لاگ میگیریم. این به این معنی هست هربار در برنامه node خودتون دارید loop میزنید در حقیقت دارید به Node خیانت میکنین. به هیچ عنوان روی آرایه های بزرگ از متد های foreach, map ,every و ... استفاده نکنید.
بعد با http ماژول یک وب سرور ساده مینویسیم
import http from "node:http";
function cpuBlockingTask() {
for (let i = 0; i < 5e5; ++i) console.log(i);
}
http
.createServer((req, res) => {
cpuBlockingTask(); // Block event loop
res.end("Done"); // Send response after loop
})
.listen(3000, () => console.log("Server is listning on port", 3000));
روی پورت 3000 یک وب سرور داریم که بعد از انجام دادن کار cpuBlockingTask یک 200 با متن Done میفرسته. سرور رو ران کنید.
یک ابزار هست به اسم AutoCannon برای Load test های ساده استفاده میشه. حجم زیادی از ریکوست رو میفرستیم سمت سرور.
https://www.npmjs.com/package/autocannon
توپ رو شلیک میکنیم سمت سرور با حالت پیشفرض که داخل داکیومنت نوشته البته یک flag هم ست میکنیم تا درخواست های موفق رو بشماریم.
autocannon --renderStatusCodes localhost:3000
نتیجه در سیستم من : فقط ۳ ریکوست موفق با تنظیمات پیشفرض
بخش اول ❇️
ادامه پست بعدی ❇️
👍7
Node Master
امروز در گروه کانال بچه ها راجع به concurrency در #NodeJS یکم صحبت کردن من هم از این فرصت استفاده میکنم توضیحاتی بدم. این جمله رو زیاد شنیدیم #NodeJS به صورت Single thread و async هست. این جمله یک نقص بزرگ داره و آدم رو به اشتباه میندازه. کامل تر این شکل میشه…
حالا با worker thread به Node کمک میکنیم.
خیلی وارد جزیات نمیشم اول با isMainThread تشخیص میدیم آیا داخل main thread برنامه هستیم یا خیر. در thread اصلی وب سرور رو run میکنیم و کار های سخت رو میدیم به worker ها که در else block هست. نکته جذاب اینجا هست که ارتباط بین thread ها با استفاده به یک چیزی شبیه به چنل ها در #GoLang هست. برای هر ریکوستی که به سمت سرور میاد یک worker ایجاد میکنیم و وقتی کارش تموم شد done رو میفرستیم سمت کلاینت. چون thread ها با message ها مختلف با هم صحبت میکنن ما با worker.postMessage میگیم که کارمون رو انجام بده. بعد شما وقتی process.exit در worker thread انجام میدی اون thread خارج میشه و برنامه اصلی کار میکنه و اینطور میتونیم به thread اصلی بگیم که من کارم تموم شد response رو بفرست. خیلی وارد جزیات فلن نمیشیم و برنامه رو اجرا میکنیم با کامند بالا با استفاده از AutoCannon
نتیجه در سیستم من : ۶۰ ریکوست موفق با تنظیمات پیشفرض.
همینطور که میبینید با کدی که خیلی خوب نیست 20 برابر در این مثال ساده تونستیم pref رو ببریم بالاتر. حالا نکاتی که باید در نظر بگرید درمورد کد.
- این کد اصلا خوب نیست به دلیل این که در scale زیاد اگر برای هر ریکوست یک native thread باز کنیم نه تنها باعث سریع تر شدن نمیشه بلکه از یک حدی برنامه شروع به خزیدن روی زمین میکنه.
- به صورت کلی concurrency در برنامه نویسی یک تخصص سخت هست یعنی شما میتونی اینقدر عمیق بشی در این مبحث که با noscript شغلی Concurrency Expert یا Concurrency Specialist داشته باشی.
- برای concurrency هم یک سری دیزاین پترن خیلی مهم وجود داره مثل worker pool که میتونید راجع بهشون بخونید و این ادامه نکته دوم هست.
import http from "node:http";
import { fileURLToPath } from "node:url";
import { Worker, isMainThread, parentPort } from "node:worker_threads";
const __filename = fileURLToPath(import.meta.url);
if (isMainThread) {
// This code will run by main thread
http
.createServer((req, res) => {
const worker = new Worker(__filename, { stdout: true });
worker.on("exit", () => {
res.end("Done");
});
worker.postMessage(null);
})
.listen(3000, () => console.log("Server is listning on port", 3000));
} else {
// This code will run by workers
function cpuBlockingTask() {
for (let i = 0; i < 5e5; ++i) console.log(i);
}
parentPort.on("message", () => {
cpuBlockingTask(); // Run Blocking Task on worker thread
process.exit(); // exit worker thread after task
});
}
خیلی وارد جزیات نمیشم اول با isMainThread تشخیص میدیم آیا داخل main thread برنامه هستیم یا خیر. در thread اصلی وب سرور رو run میکنیم و کار های سخت رو میدیم به worker ها که در else block هست. نکته جذاب اینجا هست که ارتباط بین thread ها با استفاده به یک چیزی شبیه به چنل ها در #GoLang هست. برای هر ریکوستی که به سمت سرور میاد یک worker ایجاد میکنیم و وقتی کارش تموم شد done رو میفرستیم سمت کلاینت. چون thread ها با message ها مختلف با هم صحبت میکنن ما با worker.postMessage میگیم که کارمون رو انجام بده. بعد شما وقتی process.exit در worker thread انجام میدی اون thread خارج میشه و برنامه اصلی کار میکنه و اینطور میتونیم به thread اصلی بگیم که من کارم تموم شد response رو بفرست. خیلی وارد جزیات فلن نمیشیم و برنامه رو اجرا میکنیم با کامند بالا با استفاده از AutoCannon
نتیجه در سیستم من : ۶۰ ریکوست موفق با تنظیمات پیشفرض.
همینطور که میبینید با کدی که خیلی خوب نیست 20 برابر در این مثال ساده تونستیم pref رو ببریم بالاتر. حالا نکاتی که باید در نظر بگرید درمورد کد.
- این کد اصلا خوب نیست به دلیل این که در scale زیاد اگر برای هر ریکوست یک native thread باز کنیم نه تنها باعث سریع تر شدن نمیشه بلکه از یک حدی برنامه شروع به خزیدن روی زمین میکنه.
- به صورت کلی concurrency در برنامه نویسی یک تخصص سخت هست یعنی شما میتونی اینقدر عمیق بشی در این مبحث که با noscript شغلی Concurrency Expert یا Concurrency Specialist داشته باشی.
- برای concurrency هم یک سری دیزاین پترن خیلی مهم وجود داره مثل worker pool که میتونید راجع بهشون بخونید و این ادامه نکته دوم هست.
👍19
2 روز پیش نسخه 21.6 #NodeJS منتشر شد. واقعا سرعت آپدیت #NodeJS خیلی بالا هست. از مهم ترین ویژگی هایی که اضاف شده به این نسخه.
- به permission system یک flag جدید اضافه شده که در صورت import کردن native module ها باید به صورت explicit اجازه بدین.
- حالا در این نسخه فلگ --allow-fs-* به راحتی میتونید از relative path استفاده کنید.
- یک فلگ جدید اضافه شده به اسم --build-snapshot-config. این flag کمکی هست برای build-snapshot. این flag خیلی پر استفاده برای برنامه های روزمره نیست ولی خب در آینده درمورد این flag صحبت خواهیم کرد.
https://nodejs.org/en/blog/release/v21.6.0
- به permission system یک flag جدید اضافه شده که در صورت import کردن native module ها باید به صورت explicit اجازه بدین.
node --experimental-permission --allow-addons
- حالا در این نسخه فلگ --allow-fs-* به راحتی میتونید از relative path استفاده کنید.
node --experimental-permission --allow-fs-read=./index.js
- یک فلگ جدید اضافه شده به اسم --build-snapshot-config. این flag کمکی هست برای build-snapshot. این flag خیلی پر استفاده برای برنامه های روزمره نیست ولی خب در آینده درمورد این flag صحبت خواهیم کرد.
https://nodejs.org/en/blog/release/v21.6.0
nodejs.org
Node.js — Node v21.6.0 (Current)
Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.
👍7
امروز درمورد Duck Typing صحبت میکنیم. این موضوع مربوط به رفتار زبان های dynamic type میباشد. البته این تکنیک در زبان هایی static type هم در حالت های خاصی استفاده میشود. برای درک این موضوع با مثال در #Python شروع میکنیم.
یک جمله خیلی معروف و کلیدی در این مورد وجود داره که باتوجه به اون مثال بالا رو توضیح میدیم."if it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck."
به این معنی هست "اگر شبیه به اردک شنا میکنه کواک میکنه پس احتملا اردک هست."
در زبان های dynamic type مفهومی به اسم interface نداریم و اگر یک class یک method رو تغریف کرده باشه شما بدون نیاز به type میتونید اون method رو به راحتی call کنید. الان در کد بالا هیچ نشانه ای از type نیست و فانکشن fly_test بدون داشتن دانشی از این که ایا arg ورودی fly method دارد یا خیر این متد رو call میکنه. به این کار میگن duck testing. در کل بگم به هیچ عنوان fly_test براش مهم نیست vehicle چی هست فقط براش مهم هست که fly وجود داشته باشد.
حالا سوال پیش میاد که اگر این متد نبود چی؟ الان در این مثال اگر اگر متد fly نباشه روی یکی از این کلاس ها خب runtime error داریم و برنامه crash میکنه. دو دیدگاه برای جلوگیری از این مدل runtime error ها داریم که در پست بعدی برسی میکنیم هردو رو.
نکته جالب دیگه این هست که Airplane و Duck این دو کلاس هیچ رابطه ای با هم ندارند و صرفا فقط به صورت قراردادی هردو یک fly method رو implement کردن. در #TypeScript از Duck Testing زیاد استفاده میشه برای داشتن کد TypeSafe در حقیقت تکنیک Type Predict به نوعی Duck Test میتونه محسوب بشه.
این مقدمه ای برای این بحث بود. در حقیقت برای داشتن همچین مدل رفتاری مدل های فکری مختلفی در زبان های مختلف هست. در زبان #Java ما از inerface ها و abstract class ها استفاده میکنیم در #GoLang شما یک نوع دیگه از Duck Typing رو میبینید که بهش میگن Structural Typing و interface های golang بهمون کمک میکنن در #TypeScript هم Structural Typing به شدت مرسوم هست و مثال خواهیم زد، در پایتون که Duck Typing رو دیدید ولی نکته جالب اینجا هست که Structural Typing و abstract class ها هم در پایتون خیلی بهمون کمک میکنن ولی خب کمتر کسی از وجود این ها خبر داره.
این نکته هم بگم که هیچ کدوم از این راه حل ها نسبت به دیگری برتری خاصی ندارند صرفا نوع تفکره بیشتر البته البته زبان های Static و TypeSafe میتونن develop رو راحت تر کنن در این مورد. این که کدوم تکنیک در کدوم زبان استفاده میشه مهم هست چون که به عنوان مثال Duck Typing در java خیلی مرسوم نیست و استفاده ازش سخت تره اما در یک حالت های خاصی خیلی میتونه در این زبان کمک کنه.
#Tip
class Duck:
def fly(self):
print("quak quak !")
class Airplane:
def fly(self):
print("boom boom !")
#Duck Test
def fly_test(vehicle):
vehicle.fly()
flyable = [Duck() , Airplane()]
for f in flyable:
fly_test(f)
یک جمله خیلی معروف و کلیدی در این مورد وجود داره که باتوجه به اون مثال بالا رو توضیح میدیم."if it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck."
به این معنی هست "اگر شبیه به اردک شنا میکنه کواک میکنه پس احتملا اردک هست."
در زبان های dynamic type مفهومی به اسم interface نداریم و اگر یک class یک method رو تغریف کرده باشه شما بدون نیاز به type میتونید اون method رو به راحتی call کنید. الان در کد بالا هیچ نشانه ای از type نیست و فانکشن fly_test بدون داشتن دانشی از این که ایا arg ورودی fly method دارد یا خیر این متد رو call میکنه. به این کار میگن duck testing. در کل بگم به هیچ عنوان fly_test براش مهم نیست vehicle چی هست فقط براش مهم هست که fly وجود داشته باشد.
حالا سوال پیش میاد که اگر این متد نبود چی؟ الان در این مثال اگر اگر متد fly نباشه روی یکی از این کلاس ها خب runtime error داریم و برنامه crash میکنه. دو دیدگاه برای جلوگیری از این مدل runtime error ها داریم که در پست بعدی برسی میکنیم هردو رو.
نکته جالب دیگه این هست که Airplane و Duck این دو کلاس هیچ رابطه ای با هم ندارند و صرفا فقط به صورت قراردادی هردو یک fly method رو implement کردن. در #TypeScript از Duck Testing زیاد استفاده میشه برای داشتن کد TypeSafe در حقیقت تکنیک Type Predict به نوعی Duck Test میتونه محسوب بشه.
این مقدمه ای برای این بحث بود. در حقیقت برای داشتن همچین مدل رفتاری مدل های فکری مختلفی در زبان های مختلف هست. در زبان #Java ما از inerface ها و abstract class ها استفاده میکنیم در #GoLang شما یک نوع دیگه از Duck Typing رو میبینید که بهش میگن Structural Typing و interface های golang بهمون کمک میکنن در #TypeScript هم Structural Typing به شدت مرسوم هست و مثال خواهیم زد، در پایتون که Duck Typing رو دیدید ولی نکته جالب اینجا هست که Structural Typing و abstract class ها هم در پایتون خیلی بهمون کمک میکنن ولی خب کمتر کسی از وجود این ها خبر داره.
این نکته هم بگم که هیچ کدوم از این راه حل ها نسبت به دیگری برتری خاصی ندارند صرفا نوع تفکره بیشتر البته البته زبان های Static و TypeSafe میتونن develop رو راحت تر کنن در این مورد. این که کدوم تکنیک در کدوم زبان استفاده میشه مهم هست چون که به عنوان مثال Duck Typing در java خیلی مرسوم نیست و استفاده ازش سخت تره اما در یک حالت های خاصی خیلی میتونه در این زبان کمک کنه.
#Tip
👍11
https://www.linkedin.com/posts/amir-honarmand-zade_aepaebaesaewaexaepaet-nodejs-aetaecaevaex-activity-7153837711496261632-gH3G?utm_source=share&utm_medium=member_android
#Work
#Work
Linkedin
#استخدام #nodejs #مشهد | amir honarmand
🔶 استخدام برنامه نویس تازه کار Node.js در مشهد
🔸مواردی که بهتر است تا حدودی بلد باشید:
🔹javaScript
🔹node.js
🔹nest.js
🔹express.js
دوستانی که تمایل به همکاری دارند لطفاً پیام بدن.
ممنون میشم پست رو لایک کنید.
#استخدام
#nodejs
#مشهد
🔸مواردی که بهتر است تا حدودی بلد باشید:
🔹javaScript
🔹node.js
🔹nest.js
🔹express.js
دوستانی که تمایل به همکاری دارند لطفاً پیام بدن.
ممنون میشم پست رو لایک کنید.
#استخدام
#nodejs
#مشهد
این پست رو لینکدین گذاشتم.
درمورد مقدس نبودن clean code و design patterns ها نکاتی گفتم.
شاید بدردتون بخوره
https://www.linkedin.com/posts/imanhpr_clean-code-horrible-performance-activity-7155431493845069824-TSsf?utm_source=share&utm_medium=member_android
درمورد مقدس نبودن clean code و design patterns ها نکاتی گفتم.
شاید بدردتون بخوره
https://www.linkedin.com/posts/imanhpr_clean-code-horrible-performance-activity-7155431493845069824-TSsf?utm_source=share&utm_medium=member_android
Linkedin
Iman Hosseini Pour on LinkedIn: "Clean" Code, Horrible Performance
این پست دوستمون من رو یاد یک جمله قشنگ که داخل The zen of #python هست انداخت که میگه.
"Although practicality beats purity"
اگر به این جمله دقت کنیم میتونیم این…
"Although practicality beats purity"
اگر به این جمله دقت کنیم میتونیم این…
👍9
دوستان جدیدتر راستی برای چنل یک گروه داریم درمورد مفاهیم برنامه نویسی و پرسش پاسخ هست دوست داشتید خوشحال میشیم جوین بشید.
@nodemastergp
@nodemastergp
Node Master
امروز درمورد Duck Typing صحبت میکنیم. این موضوع مربوط به رفتار زبان های dynamic type میباشد. البته این تکنیک در زبان هایی static type هم در حالت های خاصی استفاده میشود. برای درک این موضوع با مثال در #Python شروع میکنیم. class Duck: def fly(self): …
قبلا درمورد Type Predict ها در #TypeScript صحبت کردیم از این لینک یک مطالعه کنید
https://news.1rj.ru/str/NodeMaster/90
و این که یک قسمت گفتیم که دو دیدگاه برای فیکس کردن همچین crash هایی در Runtime وجود دارد.
- Easier to ask for forgiveness than permission (EAFP)
- Look before you leap (LBYL)
قبل از این که درمورد این دو دیدگاه صحبت کنیم باید بگم که هرکدوم از این ها در یک زبان هایی مرسوم هست. به عنوان مثال در #Python نماد کد تمیز استفاده از EAFP و در #Javanoscript باید از LBYL استفاده کرد.
خودتون یکم برید راجع به این دوتا مطالعه کنید و بنظرتون بگید که Type Predict ها در #TypeScript از کدوم از این استایل ها استفاده میکنن؟
https://news.1rj.ru/str/NodeMaster/90
و این که یک قسمت گفتیم که دو دیدگاه برای فیکس کردن همچین crash هایی در Runtime وجود دارد.
- Easier to ask for forgiveness than permission (EAFP)
- Look before you leap (LBYL)
قبل از این که درمورد این دو دیدگاه صحبت کنیم باید بگم که هرکدوم از این ها در یک زبان هایی مرسوم هست. به عنوان مثال در #Python نماد کد تمیز استفاده از EAFP و در #Javanoscript باید از LBYL استفاده کرد.
خودتون یکم برید راجع به این دوتا مطالعه کنید و بنظرتون بگید که Type Predict ها در #TypeScript از کدوم از این استایل ها استفاده میکنن؟
Telegram
Node Master
یکی از قابلیت های خیلی خوب #typenoscript که خیلی کم استفاده میشه "type predicate" هست. به این شکل هست که شما در runtime میتونید یک interface رو valid کنید. همونطور که میدونید interface ها در typenoscript کلا در کد transpile نمیشوند و معمولا اکثرا با استفاده از…
👍1
Node Master
قبلا درمورد Type Predict ها در #TypeScript صحبت کردیم از این لینک یک مطالعه کنید https://news.1rj.ru/str/NodeMaster/90 و این که یک قسمت گفتیم که دو دیدگاه برای فیکس کردن همچین crash هایی در Runtime وجود دارد. - Easier to ask for forgiveness than permission (EAFP)…
اینجا هم یک نمونه از Duck Typing قبلا در یکی از پست ها گفته بودم که به عنوان سوال بود.
https://news.1rj.ru/str/NodeMaster/118
https://news.1rj.ru/str/NodeMaster/118
Telegram
Node Master
خب هنوز یک قدم میخوایم پا رو فراتر بزاریم و class رو در runtime بسازیم. اول این که در #Javanoscript کلاس ها در حقیقت همون فانکشن ها هستن و صرفا کلمه class یک syntactic sugar روی نسخه ES5 هست. کلمه class در آپدیت معروف ES6 به #Javanoscript اضافه شد.
یعنی این دوتا…
یعنی این دوتا…
👍3
یک ابزار جدید از سمت مایکروسافت برای #TypeScript معرفی شده به اسم TypeSpec.
کارای زیادی میتونه کنه.
خودم چیز زیادی ازش نمیدونم ولی یک نگاهی شما هم دوست داشتید بندازید.
https://typespec.io/
#Weekly
کارای زیادی میتونه کنه.
خودم چیز زیادی ازش نمیدونم ولی یک نگاهی شما هم دوست داشتید بندازید.
https://typespec.io/
#Weekly
👍8
#Work
https://www.linkedin.com/posts/amir-honarmand-zade_aepaebaesaewaexaepaet-nodejs-aetaecaevaex-activity-7153837711496261632-gH3G?utm_source=share&utm_medium=member_android
تشکر از بچه های گروه که این کار رو معرفی کردن.
دوستان اگر دوست داشتید به گروه اینجا جوین بشید.
@nodemasterGp
https://www.linkedin.com/posts/amir-honarmand-zade_aepaebaesaewaexaepaet-nodejs-aetaecaevaex-activity-7153837711496261632-gH3G?utm_source=share&utm_medium=member_android
تشکر از بچه های گروه که این کار رو معرفی کردن.
دوستان اگر دوست داشتید به گروه اینجا جوین بشید.
@nodemasterGp
Linkedin
#استخدام #nodejs #مشهد | amir honarmand
🔶 استخدام برنامه نویس تازه کار Node.js در مشهد
🔸مواردی که بهتر است تا حدودی بلد باشید:
🔹javaScript
🔹node.js
🔹nest.js
🔹express.js
دوستانی که تمایل به همکاری دارند لطفاً پیام بدن.
ممنون میشم پست رو لایک کنید.
#استخدام
#nodejs
#مشهد
🔸مواردی که بهتر است تا حدودی بلد باشید:
🔹javaScript
🔹node.js
🔹nest.js
🔹express.js
دوستانی که تمایل به همکاری دارند لطفاً پیام بدن.
ممنون میشم پست رو لایک کنید.
#استخدام
#nodejs
#مشهد
Node Master
امروز درمورد Duck Typing صحبت میکنیم. این موضوع مربوط به رفتار زبان های dynamic type میباشد. البته این تکنیک در زبان هایی static type هم در حالت های خاصی استفاده میشود. برای درک این موضوع با مثال در #Python شروع میکنیم. class Duck: def fly(self): …
برای درک مفهوم Duck Test و کلا Duck Typing میتونیم با این مثال درمورد Promise ها نکاتی یاد بگیریم. فرض کنید فانکشنی داریم که یک Promise رو میگیره و حالا یک کاری انجام میده.
مثال خیلی ساده هست. به این نکته توجه کنید که ما اینجا هیچ نوع type check نداریم. و برنامه میتونه در runtime به مشکل بخوره اگر workPromise یک instance از Promise نباشد. توجه کنید ما همین الان هم داریم از Duck Typing استفاده میکنیم چون در doWork هیچ خبری نداریم و فقط then رو call میکنیم با فرض این که Promise یا Duck باشد.
حالا کد رو یکم بهتر میکنیم.
در "node:util" یک namespace داریم به اسم type که در اینجا یک سری فانکشن کمکی برای چک کردن تایپ ها ( Type predict function ) داریم که به ما کمک میکنن که کد safe تر باشه. الان این کد رو اگر اجرا کنید همه چیز اوکی هست و کار میکنه. ولی یک edge case اینجا وجود داره که خیلی کمتر به چشم میاد. با مثال بعد متوجه میشید ولی بزارید اول با یک سوال مطرح کنم موضوع رو.
اگر Promise Object ما از Native Promise خود #Javanoscript نباشد چه اتفاقی پیش میاد؟ قطعا این کد به مشکل میخوره چون isPromise فقط Native Promise ها رو چک میکنه و نه 3rd party ها که ممکنه در خیلی از code base ها باشه.
به عنوان مثال اگر از پکیج زیر استفاده شده باشه.
https://www.npmjs.com/package/promise
حالا اگر فقط این پکیج import شده باشه این کد به مشکل میخوره
حالا شما میگی ایمان خب با شرط رو با instaceof چک میکنیم که اگر این پکیج بود درست اجرا بشه. و شرط رو به این شکل عوض میکنید.
دوباره اینجا یک مشکل پیش میاد چون فقط همین یک پکیج نیست. به عنوان مثال اگر bluebird استفاده کرده باشن کد مشکل میخوره. خب منظورم رو تا الان متوجه شدین بریم سراغ Duck Test. اون جمله معروف که در پست اول گفتیم رو به یاد بیارید اول و حالا دقت کنید.
درسته این پکیج ها متفاوت هستند ولی همشون interface های یکسانی دارند. اینجا دوست دارم یک رفرنس بزنم به یک جمله معروف که اگر عمیق درکش کنید چند level یک شبه در برنامه نویسی پیشرفت میکنید.
"program to interfaces, not implementations"
اینجا دقیقا این lib ها از این مفهوم استفاده کردند برای Promise به ما implementation های زیادی داریم ولی نقطه مشترک همشون داشتن interface یکسان هست که به عنوان مثال همشون متد .then دارند. اصن وقتی در مثال بالا ما بدون تغییر کد فقط با import کردن کل ساختار رو عوض کردیم که کد به مشکل خورد مثال همین موضوع هست.
حالا کافیه با استناد به این جمله کلیدی و زیبا و Duck Test و فرض گرفتن که همه این lib ها متد .then رو دارند شرط رو عوض کنیم.
حالا شما اگر شرط بالا رو به این صورت بنویسید (دقیقا مثل type predict ها در #TypeScript) میبینید که کد با هر library کار میکنه. چون شما وابستگی خودتون رو از implementation شکوندین و به interface وابسته شدین. مهم نیست که object ورودی یک instance از Promise خاصی باشد. مهم این هست که شبیه به Promise ها رفتار کند ( به عنوان مثال متد .then داشته باشد).
این بود مفهوم Duck Test به صورت کاربردی. توجه کنید که کد بالا به صورت production ready نیست و صرفا فقط برای توضیح مفاهیم بود.
امیدوارم خوشتون اومده باشه.
#Tip
#NodeJS
function doWork(promise) {
promise.then(() => {
console.log("Work Is Done");
});
}
const newPromise = Promise.resolve("Hello Promise");
doWork(newPromise);مثال خیلی ساده هست. به این نکته توجه کنید که ما اینجا هیچ نوع type check نداریم. و برنامه میتونه در runtime به مشکل بخوره اگر workPromise یک instance از Promise نباشد. توجه کنید ما همین الان هم داریم از Duck Typing استفاده میکنیم چون در doWork هیچ خبری نداریم و فقط then رو call میکنیم با فرض این که Promise یا Duck باشد.
حالا کد رو یکم بهتر میکنیم.
import { types } from "node:util";
function doWork(promise) {
if (types.isPromise(promise)) {
promise.then(() => {
console.log("Work Is Done");
});
}
}در "node:util" یک namespace داریم به اسم type که در اینجا یک سری فانکشن کمکی برای چک کردن تایپ ها ( Type predict function ) داریم که به ما کمک میکنن که کد safe تر باشه. الان این کد رو اگر اجرا کنید همه چیز اوکی هست و کار میکنه. ولی یک edge case اینجا وجود داره که خیلی کمتر به چشم میاد. با مثال بعد متوجه میشید ولی بزارید اول با یک سوال مطرح کنم موضوع رو.
اگر Promise Object ما از Native Promise خود #Javanoscript نباشد چه اتفاقی پیش میاد؟ قطعا این کد به مشکل میخوره چون isPromise فقط Native Promise ها رو چک میکنه و نه 3rd party ها که ممکنه در خیلی از code base ها باشه.
به عنوان مثال اگر از پکیج زیر استفاده شده باشه.
https://www.npmjs.com/package/promise
حالا اگر فقط این پکیج import شده باشه این کد به مشکل میخوره
import Promise from "promise";
حالا شما میگی ایمان خب با شرط رو با instaceof چک میکنیم که اگر این پکیج بود درست اجرا بشه. و شرط رو به این شکل عوض میکنید.
import Promise from "promise";
import { types } from "node:util";
function doWork(promise) {
if (types.isPromise(promise) || promise instanceof Promise) {
promise.then(() => {
console.log("Work Is Done");
});
}
}
دوباره اینجا یک مشکل پیش میاد چون فقط همین یک پکیج نیست. به عنوان مثال اگر bluebird استفاده کرده باشن کد مشکل میخوره. خب منظورم رو تا الان متوجه شدین بریم سراغ Duck Test. اون جمله معروف که در پست اول گفتیم رو به یاد بیارید اول و حالا دقت کنید.
درسته این پکیج ها متفاوت هستند ولی همشون interface های یکسانی دارند. اینجا دوست دارم یک رفرنس بزنم به یک جمله معروف که اگر عمیق درکش کنید چند level یک شبه در برنامه نویسی پیشرفت میکنید.
"program to interfaces, not implementations"
اینجا دقیقا این lib ها از این مفهوم استفاده کردند برای Promise به ما implementation های زیادی داریم ولی نقطه مشترک همشون داشتن interface یکسان هست که به عنوان مثال همشون متد .then دارند. اصن وقتی در مثال بالا ما بدون تغییر کد فقط با import کردن کل ساختار رو عوض کردیم که کد به مشکل خورد مثال همین موضوع هست.
حالا کافیه با استناد به این جمله کلیدی و زیبا و Duck Test و فرض گرفتن که همه این lib ها متد .then رو دارند شرط رو عوض کنیم.
function doWork(promise) {
if (promise && promise.then && typeof promise.then === "function") {
promise.then(() => {
console.log("Work Is Done");
});
}
}حالا شما اگر شرط بالا رو به این صورت بنویسید (دقیقا مثل type predict ها در #TypeScript) میبینید که کد با هر library کار میکنه. چون شما وابستگی خودتون رو از implementation شکوندین و به interface وابسته شدین. مهم نیست که object ورودی یک instance از Promise خاصی باشد. مهم این هست که شبیه به Promise ها رفتار کند ( به عنوان مثال متد .then داشته باشد).
این بود مفهوم Duck Test به صورت کاربردی. توجه کنید که کد بالا به صورت production ready نیست و صرفا فقط برای توضیح مفاهیم بود.
امیدوارم خوشتون اومده باشه.
#Tip
#NodeJS
👍11
Node Master
برای درک مفهوم Duck Test و کلا Duck Typing میتونیم با این مثال درمورد Promise ها نکاتی یاد بگیریم. فرض کنید فانکشنی داریم که یک Promise رو میگیره و حالا یک کاری انجام میده. function doWork(promise) { promise.then(() => { console.log("Work Is Done");…
اگر تمام این مفاهیم که تا الان باهم یاد گرفتیم رو بخواهیم بندازیم دور و فقط و فقط یکیش رو یاد بگیریم. همین جمله معروف
"program to interfaces, not implementations"
میتونید درموردش داخل این stack overflow بیشتر یاد بگیرید.
https://stackoverflow.com/questions/2697783/what-does-program-to-interfaces-not-implementations-mean
تجربه شخصی : زندگی من بعد از درک این جمله قشنگ دو تیکه شد. قبل از یاد گرفتن این و بعد از یاد گرفتنش. یادمه از شدت خوشحالی که چقدر این موضوع قوی و باحاله اشک تو چشام جمع شده بود. و آرزو میکردم ای کاش خیلی قبل تر یکی این موضوع رو بهم میگفت.
"program to interfaces, not implementations"
میتونید درموردش داخل این stack overflow بیشتر یاد بگیرید.
https://stackoverflow.com/questions/2697783/what-does-program-to-interfaces-not-implementations-mean
تجربه شخصی : زندگی من بعد از درک این جمله قشنگ دو تیکه شد. قبل از یاد گرفتن این و بعد از یاد گرفتنش. یادمه از شدت خوشحالی که چقدر این موضوع قوی و باحاله اشک تو چشام جمع شده بود. و آرزو میکردم ای کاش خیلی قبل تر یکی این موضوع رو بهم میگفت.
Stack Overflow
What does "program to interfaces, not implementations" mean?
One stumbles upon this phrase when reading about design patterns.
But I don't understand it, could someone explain this for me?
But I don't understand it, could someone explain this for me?
👍8