ترید شاهین 💸 | 🕋𝐈𝐍 𝐆𝐎𝐃 𝐖𝐄 𝐓𝐑𝐔𝐒𝐓
آموزش صفر تا 100 کریپتو 📊
❗️معرفی خفن ترین پروژه ها در بازار های مالی به صورت رایگان🐳
سیگنال فیوچرز و اسپات (هولد) رایگان🔥
با ما باشی💯 قدم جلویی رفیق🥂
𝐈𝐍𝐒𝐓𝐀𝐆𝐑𝐀𝐌 :
www.instagram.com/trade_shahin
Last updated 6 days, 23 hours ago
[ We are not the first, we try to be the best ]
Last updated 2 months, 1 week ago
FAST MTPROTO PROXIES FOR TELEGRAM
Ads : @IR_proxi_sale
Last updated 1 month, 3 weeks ago
باشد تا رستگار شویم.🔥
"node".split('').sort().join('')
مدت زیادی هست که #Redis Stack منتشر شده ولی هنوز خیلی ها به Redis به چشم یک دیتابیس Key-Value ساده نگاه میکنند و از 90 درصد قابلیت هاش استفاده نمیکنند. پیشنهاد میکنم داکیومنت مربوط بهش رو حتما بخونیدتا تمام ویژگی هایی رو که داره ببینید. دوتا از ویژگی های خوبی…
مدت زیادی هست که #Redis Stack منتشر شده ولی هنوز خیلی ها به Redis به چشم یک دیتابیس Key-Value ساده نگاه میکنند و از 90 درصد قابلیت هاش استفاده نمیکنند. پیشنهاد میکنم داکیومنت مربوط بهش رو حتما بخونیدتا تمام ویژگی هایی رو که داره ببینید.
دوتا از ویژگی های خوبی که Redis Stack داره به اسم Redis Search و Redis JSON هست.
- تا قبل از Redis JSON برای ذخیره کردن JSON ها در Redis، معادل Serialize شده رو به صورت Key-Value ذخیره میکردن و یا گاهی به صورت Map باهاش رفتار میکردن. حالا شما با Redis JSON میتونید مثل یک document oriented database مثل MongoDB رفتار کنید. ( البته Query ها به صورت پیش فرض محدودیت هایی دارند )
- تا قبل از Redis Search برای سرچ کردن تنها گزینه موجود استفاده از Glob Pattern ها بود که حتی داخل خود داکیومنت هم پیشنهاد کرده بودن که اگر روی Production هستید سعی کنید زیاد استفاده از Glob pattern نکنید. و این موضوع با در نظر گرفتن این نکته که Redis به صورت ذاتی Single thread هست و Event loop رو با این کار در حجم زیاد دیتا بلاک میکنید منطقی هست. البته این موضوع برای دوستان #JavaScript و #NodeJS کاملا به صورت واضح قابل درک هست. حالا شما با استفاده از Redis Search میتونید روی دیتا مورد نظرتون Index بزارید و باتوجه به اون Index و Schema که تعریف کردین Query بزنید و دیتا رو خیلی سریع و تمیز دریافت کنید. انتظار قدرت SQL و بقیه دیتابیس ها مثل MongoDB رو نداشته باشید ولی در بعضی سناریو ها واقعا ترکیب Redis Json و Redis Search میدرخشه.
در این مثال با نحوه کار کردن با Redis JSON آشنا میشیم و در پست بعدی با Redis Search یک خورده کار میکنیم.
به صورت کلی شما با استفاده از "JSON" میتونید دسترسی به namespace مربوط بهش رو داشته باشید و با json ها کار کنید.
- ایجاد یک Json doc جدید
JSON.SET key path value
با استفاده از JSON.SET میتونید JSON به راحتی ذخیره کنید. در اینجا key منظور از همون کلید عادی هست نکته خاصی نداره ( در Redis Search درموردش بیشتر صحبت میکنیم ). منظور از Path اینجا مسیر JsonPath هست که با استفاده از اون میتونید فیلتر های مختلف روی دیتا Json بزارید و بخش خاصی رو فقط بخونید یا آپدیت کنید ( معادل Xpath برای داده های XML ). برای این که بتونیم یک دیتا json ذخیره کنیم خب ما میخوایم در مسیر Root این کلید ذخیره کنیم و با استفاده از "$" مشخص میکنیم که میخوایم روی Root ذخیره کنیم.
JSON.SET user:1 $ '{"name": "Iman", "age": 25, "city": "Bushehr"}'
حالا اگر بخوام فقط بخش name رو بخونم از این به این صورت عمل میکنم.
JSON.GET user:1 "name"
یا اگر بخوام شهر رو آپدیت کنم به تهران.
JSON.SET user:1 $.city '"Tehran"'
حالا اگر بخوایم کل دیتا بخونیم و نتیجه رو ببینیم.
JSON.GET user:1
یک نکته خیلی مهم و ریز درمورد آپدیت بگم. جایی که دیتا رو قرار میدیم یعنی '"Tehran"' هر مدل دیتایی میخواد باشه مثل اینجا که یک string ساده هست. باید یک parser مربوط به JSON بتونه به صورت Valid این دیتا رو Serialize کنه. به عنوان مثال یعنی عبارت زیر در #JavaScript باید بدون هیچ خطایی کار کنه.
```
JSON.stringify("Tehran")
'"Tehran"'
```
در صورتی که JSON.stringify به شما خروجی داد شما اون دیتا رو میتونید به عنوان value استفاده کنید.
حالا برا این که مثال رو یکم جالب تر کنیم یک Json دیگ رو داخل این Embed میکنیم.
JSON.SET user:1 $.address '{"zipCode":1234}'
JSON.GET user:1 $.address.zipCode
در پست بعدی به Redis Search نگاه میندازیم و اگر انرژی هم موند یکی از مهم ترین و اساسی ترین نکات Redis که دونستنش میتونه مثل مرگ و زندگی باشه یعنی Atomicity رو برسی میکنیم.
امیدوارم موفق باشید.
یکی از نکات زیبا که درمورد #Deno و #JSR که وجود داره این هست که شما میتونید از پکیج های std دینو در #NodeJS استفاده کنید. همشون نه ولی به اکثرشون دسترسی دارید. به لینک زیر یک نگاهی بندازید و مشخصا میبینید که کدوم پکیج ها رو میتونید در پروژه #NodeJS خودتون استفاده کنید.
https://jsr.io/@std
به عنوان مثال پکیج @std/msgpack به پروژه خودمون اضافه میکنیم.
npx jsr add @std/msgpack
و بعد کد زیر رو با #NodeJS اجرا کنید.
```
import * as msgpack from "@std/msgpack";
const data = { name: "node-master" };
const enc = msgpack.encode(data);
const dec = msgpack.decode(enc);
console.log(dec);
```
حالا سوال پیش میاد که اصلا چرا همچین کاری باید کنیم. باتوجه به این که #JavaScript خودش std بزرگی مثل #Python یا #Java نداره گاهی اوقات نیاز به یک سری کدهای کمکی برای پروژه خودتون دارید و پکیج هایی مثل Lodash, es-toolkit کمک بزرگی کردن. اما حالا #Deno هم با این کار به اکوسیستم کمک بزرگی کرده و یک رنج از ابزار های کمکی که ممکنه در loadash و بقیه شبیهه بهش پیدا نکنید رو شاید اینجا پیدا کنید.
به عنوان مثال اگر پروژه کوچیکی دارید که فقط یک instance از server شما وجود داره استفاده از ابزاری مثل #Redis صرفا برای Cache زیاد منطقی نیست و خب در اکثرا اوقات یک Map ساده مشکل شما رو میتونه حل کنه. اگر ویژگی TTL هم بخواید داشته باشید خودتون میتونید پیاده سازی کنید با کمک Map ولی معمولا از پکیج node-cache در این سناریو استفاده میکنن. حالا یک گزینه دیگ داریم که مربوط به #Deno std هست.
https://jsr.io/@std/cache
این پکیج جدا از مثال بالا مدل های مختلف دیگ از cache رو در اختیار شما میزاره که نگاهی بندازید و جالبه.
نسخه 20.16 LTS مربوط به #NodeJS خیلی وقته اومده و خب چون مدتی فعال نبودیم. از دست ما در رفته نگاهی بهش بندازیم.
یک فانکشن کمکی به این نسخه اضافه شده و از این زاویه جالب هست که یک حرکت eco system رو نشون میده که برای ما developer ها در در طولانی مدت میتونه خوب باشه. این که در آینده کدهای بیشتری ببینیم که به runtime خاصی وابسته نباشن و فریم ورک های جدید تر روی هر runtime به صورت native اجرا بشه.
فانکشن کمکی جدید process.getBuiltinModule
این فانکشن به ما کمک میکنه که در runtime هر ماژولی رو از std مربوط به #NodeJS به راحتی import کنیم. حالا سوال پیش میاد که چرا از خود ES import استفاده نمیکنیم. به این دلیل که اگر یک کد داشته باشیم که به #Deno وابستگی داره حالا اگر بخواهیم اون کد رو با #NodeJS ران کنیم بره و از std مربوط به Node استفاده کنه و نه Deno. بزارید با مثال این رو ببینیم. نمونه ای خوب و ساده از Factory pattern و Polymorphism هم میشه دید. اگر تازه کارتر هستید و در حال یادگیری به این مثال بیشتر دقت کنید خیلی بهتون کمک خواهد کرد.
```
class DenoReader {
constructor() {
this.decoder = new TextDecoder();
}
readFile(fileName) {
const byteArray = Deno.readFileSync(fileName);
const result = this.decoder.decode(byteArray);
return result;
}
}
class NodeReader {
constructor() {
this.fs = globalThis.process.getBuiltinModule("fs");
}
readFile(fileName) {
const result = this.fs.readFileSync(fileName).toString("utf-8");
return result;
}
}
function getReader() {
switch (true) {
case globalThis.Deno !== undefined:
return new DenoReader();
case globalThis.process.getBuiltinModule !== undefined:
return new NodeReader();
default:
throw new Error("No Reader available");
}
}
const nodeReader = getReader();
const nodeResult = nodeReader.readFile("my-text.txt");
console.log(nodeResult);
```
هدف خوندن یک فایل از روی disk هست و البته که این کد برای runtime های #Deno و #NodeJS از Native API مربوط به هر runtime استفاده کنه. باتوجه به این که این runtime ها هرکدوم دنیای خودشون رو دارن و API های خاص خودشون. اول باید یک API مشترک برای این دوتا بسازیم که بتونیم به هدفمون برسیم. اینجا Factory pattern به کمک ما میاد که بهمون اجازه میده با استفاده از type switch تصمیم بگیریم که روی کدام runtime هستیم و با توجه به اون runtime کلاس reader مربوط بهش رو بهمون میده و البته با استفاده از Duck typing در #JavaScript یا با استفاده از interface ها در #TypeScript یک interface یکسان برای خواندن فایل با دو implemetion متفاوت باید ایجاد کنیم که در بالا معادل NodeReader و DenoReader هست که readFile میشه interface یکسان بین این دو.
نکته قابل توجه این که چون اینجا مشخص نیست کدوم runtime رو قراره استفاده کنیم، استفاده از top-level import به صورت کلی کنسل هست به این دلیل که اگر کد زیر بزاریم و برنامه با Deno ران کنیم کلا هدفمون میره تو دیوار.
import fs from "node:fs";
یک سوال دیگ که پیش میاد دقیقا همین ویژگی رو ما میتونیم با استفاده از dynamic import داشته باشیم چرا از اون استفاده نکنیم؟ در جواب این موضوع مشکل خیلی خاصی به وجود نمیاد. مزیت این روش نسبت به dynamic import این هست که این روش به صورت sync فرایند import رو انجام میده درصورتی که حاصل dynamic imprort یک Promise هست که اگر ESM باشید با top-level await میتونید تمیز حلش کنید. اما اگر روی CJS باشید کثیف کاری خواهید داشت در نتیجه در این سناریو این روش جدید منطقی تر به نظر میرسه.
قبلا هم درمورد Duck typing مفصل صحبت کرده بودیم که اینجا میتونید ببینید اگر دوست داشتید.
https://t.me/NodeMaster/136
ترید شاهین 💸 | 🕋𝐈𝐍 𝐆𝐎𝐃 𝐖𝐄 𝐓𝐑𝐔𝐒𝐓
آموزش صفر تا 100 کریپتو 📊
❗️معرفی خفن ترین پروژه ها در بازار های مالی به صورت رایگان🐳
سیگنال فیوچرز و اسپات (هولد) رایگان🔥
با ما باشی💯 قدم جلویی رفیق🥂
𝐈𝐍𝐒𝐓𝐀𝐆𝐑𝐀𝐌 :
www.instagram.com/trade_shahin
Last updated 6 days, 23 hours ago
[ We are not the first, we try to be the best ]
Last updated 2 months, 1 week ago
FAST MTPROTO PROXIES FOR TELEGRAM
Ads : @IR_proxi_sale
Last updated 1 month, 3 weeks ago