آشنایی با node.js
فهرست مطالب
در یکی دیگر از مقالات مربوط به برنامه نویسی برای علاقه مندان این حوزه اینبار قصد داریم به node.js بپردازیم.
node.js یکی از معروف ترین و پر کاربردترین فریمورک های جاوا اسکریپت می باشد که به معنای واقعی این زبان را تکمیل می کند.
در ادامه ما به ویژگی های کلی این زبان و نحوه ی استفاده از آن خواهیم پرداخت.
با ما همراه باشید.
برای آشنایی با جاوا اسکریپت می توانید از مقاله ی آن دیدن کنید.
node.js چیست
همانند بسیاری از فناوریها، Node.js نیز قهرمانان و مخالفان خود را دارد.
اما نمی توان انکار کرد که به طور گسترده توسط برخی از وب سایت های قدرتمند از جمله Uber، LinkedIn و PayPal استفاده می شود ؛ که آن را بدون توجه به اینکه موافق یا مخالف آن هستید، به یک نیروگاه تبدیل می کند.
Node.js یک single-threaded ، منبع باز و کراس پلتفرم برای ساخت برنامه های کاربردی شبکه و سمت سرور سریع و مقیاس پذیر است.
Node.js بر روی موتور runtime جاوا اسکریپت V8 اجرا می شود و از معماری I/O مبتنی بر event و non-blocking استفاده می کند که آن را کارآمد و برای برنامه های real-time مناسب می کند.
Node.js به زبان های C، C++ و JavaScript نوشته شده است.
به طور کلی Node برای ساختن نرمافزارها و برنامههایی که به تعاملات همزمان نیاز دارند ، مانند برنامههای چت و وبسایتها، بهترین گزینه است.
برخی از محبوب ترین پلتفرم هایی که از Node.js استفاده می کنند عبارتند از :
- Spotify
- eBay
- Godaddy
معماری node.js
Node.js از معماری “Single Threaded Event Loop” برای مدیریت همزمان چندین کلاینت استفاده می کند.
برای درک تفاوت این زمان با سایر زمانهای اجرا ، باید درک کنیم که چگونه کلاینتهای همزمان چند رشتهای در زبانهایی مانند جاوا مدیریت میشوند.
در یک مدل request-response چند رشته ای ، چندین کلاینت یک درخواست ارسال می کنند و سرور قبل از ارسال پاسخ ، هر یک را پردازش می کند.
با این حال ، چندین رشته برای پردازش کال های همزمان استفاده می شود.
این رشته ها در یک Thread Pool تعریف می شوند و هر بار که درخواستی وارد می شود، یک رشته مجزا برای رسیدگی به آن اختصاص داده می شود.
Node.js متفاوت عمل می کند.
بیایید نگاهی به هر مرحله ای که طی می کند بیاندازیم :
Node.js یک مجموعه رشته محدود را برای ارائه درخواست ها حفظ می کند.
هر زمان که درخواستی می آید ، Node.js آن را در یک صف قرار می دهد.
اکنون ، “Event loop” تک رشته ای ، کامپوننت اصلی ، وارد می شود.
این Event loop به طور نامحدود منتظر درخواست ها است.
هنگامی که یک درخواست وارد می شود ، حلقه آن را از صف انتخاب می کند و بررسی می کند که آیا به عملیات blocking input/output (I/O) نیاز دارد یا خیر.
در غیر این صورت ، درخواست را پردازش می کند و پاسخی را ارسال می کند.
اگر درخواست دارای عملیات blocking برای انجام باشد ، Event loop یک رشته از مخزن نخ داخلی برای پردازش درخواست اختصاص میدهد.
Event loop درخواستهای blocking را دنبال میکند و پس از پردازش کار blocking ، آنها را در صف قرار میدهد.
از آنجایی که Node.js از Thread های کمتری استفاده می کند، از منابع/حافظه کمتری استفاده می کند و در نتیجه اجرای کار سریعتر انجام می شود.
بنابراین برای اهداف ما، این معماری تک رشته ای معادل معماری چند رشته ای است.
زمانی که فرد نیاز به پردازش وظایف فشرده داده دارد، استفاده از زبان های چند رشته ای مانند جاوا بسیار منطقی تر است.
اما برای برنامه های ریل تایم ، Node.js انتخاب واضح و درستی است.
ویژگی های اصلی node.js
1. یادگیری آسان
Node با جاوا اسکریپت نوشته شده است.
جاوا اسکریپت یکی از محبوب ترین زبان های برنامه نویسی است و تقریباً هر توسعه دهنده ای با آن آشنایی دارد.
بنابراین، یادگیری Node به تلاش و زمان کمتری نیاز دارد، حتی برای یک برنامه نویس جونیور جاوا اسکریپت.
2. Full Stack js
توسعه وب Full stack زمانی است که یک توسعه دهنده روی تمام جنبه های برنامه کار می کند : توسعه front-end ، توسعه back-end ، مدیریت پایگاه داده و غیره.
قبل از Node ، توسعه دهندگان full stack مجبور بودند چندین زبان را یاد بگیرند.
با Node ، فقط باید جاوا اسکریپت را بدانید تا به بک اند و فرانت اند مسلط باشید.
۳. تقاضای بازار
تقاضا برای توسعه دهندگان فول استک زیاد است و ما شاهد فرصت های شغلی بیشتری هستیم که نیاز به مهارت Node دارند.
این بدان معناست که افزودن Node.js به رزومه شما ، راه خوبی برای گسترش فرصت های شغلی شما به عنوان یک توسعه دهنده بک اند یا فرانت اند است.
۴. آزادی در ساخت اپلیکیشن ها
برخلاف زبان هایی مانند Ruby که دستورالعملها و قوانینی را برای توسعه نرمافزار تحمیل میکند،
Node آزادی عمل بیشتری را در ساخت برنامهها فراهم میکند.
۵. جامعه فعال
Node.js یک فریمورک اوپن سورس با یک جامعه بسیار فعال و پر جنب و جوش متشکل از توسعه دهندگان است که به طور مداوم در بهبود آن مشارکت دارند.
این امر یادگیری را آسان تر می کند زیرا در هر مرحله از توسعه به راه حل های متعددی دسترسی دارید.
۶. مقیاس پذیر
Node.js مقیاس پذیری گسترده ای را برای برنامه ها فراهم می کند.
Node.js که تک رشته ای است ، می تواند تعداد زیادی اتصال همزمان با توان عملیاتی بالا را مدیریت کند.
۷. سرعت
اجرای Non-blocking رشته، Node.js را سریعتر و کارآمدتر میکند.
۸. پکیج ها
مجموعه گستردهای از پکیج های منبع باز Node.js موجود است که میتواند کار شما را ساده کند.
امروزه بیش از یک میلیون پکیج در اکوسیستم NPM وجود دارد.
۹. کراس پلتفرم
پشتیبانی از پلتفرم های مختلف به شما امکان می دهد تا وب سایت ، برنامه های دسکتاپ و حتی برنامه های تلفن همراه را با استفاده از Node.js ایجاد کنید.
۱۰. بک اند قوی
Node.js به زبان های C و C++ نوشته شده است که سرعت آن را افزایش می دهد و ویژگی هایی مانند پشتیبانی از شبکه را اضافه می کند.
کاربردهای استفاده از node.js
برخی از کاربردهای Node.js عبارتند از :
چت های ریل تایم :
به دلیل ماهیت single-threaded asynchronous می توان گفت Node.js برای پردازش ارتباطات ریل تایم مناسب است.
به عنوان مثال می تواند در ساخت ربات های چت استفاده می شود.
Node.js همچنین ساخت ویژگیهای چت اضافی مانند چت چند نفره و پوش نوتیفیکیشن را نیز ساده میکند.
Data streaming :
شرکت هایی مانند Netflix از Node.js برای اهداف پخش استفاده می کنند.
این عمدتا به دلیل سبک و سریع بودن Node.js است، علاوه بر آن Node.js یک native streaming API ارائه می دهد.
این جریانها به کاربران اجازه میدهند تا درخواستهای خود را به یکدیگر ارسال کنند و در نتیجه دادهها مستقیماً به مقصد نهایی خود منتقل میشوند.
برنامه های پیچیده تک صفحه ای (SPA) :
در SPA ها ، کل برنامه در یک صفحه بارگذاری می شود.
این معمولاً به این معنی است که چند درخواست در پسزمینه برای کامپوننت های خاص وجود دارد.
event loop در Node.js به کمک می آید ، زیرا درخواست ها را به صورت non-blocking پردازش می کند.
برنامه های مبتنی بر API REST :
جاوا اسکریپت هم در قسمت فرانت اند و هم در بک اند سایت ها استفاده می شود.
بنابراین ، یک سرور می تواند به راحتی با استفاده از Node.js از طریق rest api ها با فرانت اند ارتباط برقرار کند.
Node.js همچنین پکیج هایی مانند Express.js و Koa را ارائه می دهد که ساخت وب اپلیکیشن ها را آسان تر می کند.
خب تا به اینجای کار مقدمات و آشنایی لازم در رابطه با node.js را شرح دادیم و اجازه بدهید از اینجا به بعد وارد بخش کدنویسی و عملی با آن بشویم.
ساخت یک اپ آزمایشی با node.js
قبل از ایجاد یک برنامه ی ساده (سلام دنیا) با استفاده از Node.js ، اجازه دهید اجزای یک برنامه Node.js را ببینیم.
یک برنامه Node.js از سه جزء مهم زیر تشکیل شده است :
Import ماژول های مورد نیاز : ما از دستورالعمل require برای بارگیری ماژول های Node.js استفاده می کنیم.
ساخت سرور : سروری که به درخواست های کلاینت مشابه سرور HTTP Apache گوش می دهد.
خواندن درخواست و بازگشت پاسخ : سرور ایجاد شده در مرحله قبلی ، درخواست HTTP را که توسط کلاینت انجام شده است، میخواند که میتواند یک مرورگر یا یک کنسول باشد و پاسخ را برمیگرداند.
مرحله ۱ : وارد کردن ماژول مورد نیاز :
برای بارگذاری ماژول http و ذخیره نمونه HTTP برگشتی در متغیر http از دستور require به صورت زیر استفاده می کنیم.
var http = require("http");
مرحله ۲ : ساخت سرور :
ما از نمونه http ایجاد شده استفاده می کنیم و متد () http.createServer را برای ایجاد یک نمونه سرور فراخوانی می کنیم و سپس آن را در پورت 8081 با استفاده از متد listen مرتبط با نمونه سرور متصل می کنیم.
یک تابع با پارامترهای request and response به آن ارسال کنید.
اجرای نمونه را بنویسید تا همیشه “Hello World” را برگرداند.
http.createServer(function (request, response) {
// Send the HTTP header
// HTTP Status: 200 : OK
// Content Type: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// Send the response body as "Hello World"
response.end('Hello World\n');
}).listen(8081);
// Console will print the message
console.log('Server running at http://127.0.0.1:8081/');
کد بالا برای ایجاد یک سرور HTTP کافی است و منتظر درخواستی از پورت 8081 در local machine است.
مرحله ۳ : تست Request & Response :
بیایید مرحله ۱ و ۲ را با هم در فایلی به نام main.js قرار داده و سرور HTTP خود را مانند شکل زیر راه اندازی کنیم.
var http = require("http");
http.createServer(function (request, response) {
// Send the HTTP header
// HTTP Status: 200 : OK
// Content Type: text/plain
response.writeHead(200, {'Content-Type': 'text/plain'});
// Send the response body as "Hello World"
response.end('Hello World\n');
}).listen(8081);
// Console will print the message
console.log('Server running at http://127.0.0.1:8081/');
اکنون main.js را برای راه اندازی سرور به صورت زیر اجرا کنید :
$ node main.js
خروجی را تأیید کنید ؛ سرور شروع به کار کرده است.
Server running at http://127.0.0.1:8081/
http://127.0.0.1:8081/ را در هر مرورگری باز کنید و نتیجه زیر را مشاهده کنید.
REPL Terminal
REPL مخفف Read Eval Print Loop است و یک محیط کامپیوتری مانند کنسول ویندوز یا لینوکس را نشان می دهد که در آن یک فرمان وارد می شود و سیستم با یک خروجی در حالت تعاملی پاسخ می دهد.
Node.js یا با یک محیط REPL ارائه می شود.
تسک های زیر را انجام می دهد ؛
Read : ورودی کاربر را می خواند ، ورودی را در JavaScript data-structure تجزیه می کند و در حافظه ذخیره می کند.
Eval : دیتا استراکچر را می گیرد و ارزیابی می کند.
Print : نتیجه را چاپ می کند.
Loop : فرمان بالا را تا زمانی که کاربر ctrl-c را دو بار فشار دهد تکرار می کند.
ویژگی REPL Node در آزمایش کدهای Node.js و اشکال زدایی کدهای جاوا اسکریپت بسیار مفید است.
شروع کار با REPL :
REPL را می توان با اجرای نود روی پوسته/کنسول بدون هیچ آرگومان به شرح زیر شروع کرد.
$ node
خط فرمان REPL را خواهید دید که در آن می توانید هر دستور Node.js را تایپ کنید.
$ node
>
مثال :
$ node
> var x = 10
undefined
> var y = 20
undefined
> x + y
30
> var sum = _
undefined
> console.log(sum)
30
undefined
>
دستورات REPL :
- ctrl + c : دستور فعلی را خاتمه دهید.
- ctrl + c دو بار : Node REPL را خاتمه دهید.
- ctrl + d : Node REPL را خاتمه دهید.
- Up/Down Keys ؛ تاریخچه فرمان را ببینید و دستورات قبلی را اصلاح کنید.
- tab Keys : لیستی از دستورات فعلی.
- .help : لیست تمام دستورات.
- .break : خروج از عبارت چند خطی.
- .clear : پاک کردن عبارت چند خطی.
- .save filename : سشن فعلی Node REPL را در یک فایل ذخیره کنید.
- .load filename : بارگیری محتوای فایل در سشن Node REPL فعلی.
NPM
Node Package Manager (NPM) دو قابلیت اصلی را ارائه می دهد که عبارتند از :
مخازن آنلاین برای پکیج ها / ماژول های node.js که در search.nodejs.org قابل جستجو هستند.
ابزار Command line برای نصب پکیج های Node.js ، مدیریت ورژن و مدیریت پکیج های Node.js.
NPM همراه با Node.js قابل نصب پس از نسخه 6.3 ارائه می شود.
Callbacks
Callback یک معادل ناهمزمان برای یک تابع است.
یک تابع فراخوانی پس از تکمیل یک کار داده شده فراخوانی می شود.
Node به شدت از callback ها استفاده می کند.
تمام API های Node به گونه ای نوشته شده اند که از callback پشتیبانی می کنند.
به عنوان مثال ، یک تابع برای خواندن یک فایل ممکن است بلافاصله کنترل را به محیط اجرا برگرداند تا دستور بعدی اجرا شود.
هنگامی که فایل ورودی/خروجی کامل شد ، همزمان با ارسال تابع callback ، محتوای فایل به عنوان پارامتر، تابع callback را فراخوانی می کند.
بنابراین هیچ blocking یا منتظر ماندن برای فایل I/O وجود ندارد.
این باعث میشود Node.js بسیار مقیاسپذیر باشد، زیرا میتواند تعداد زیادی درخواست را بدون منتظر ماندن برای بازگشت هیچ تابعی پردازش کند.
مثال :
یک فایل متنی با نام input.txt با محتوای زیر ایجاد کنید :
Manataz provides the most complete and specialized programming services
یک فایل js با نام main.js با کد زیر ایجاد کنید :
var fs = require("fs");
var data = fs.readFileSync('input.txt');
console.log(data.toString());
console.log("Program Ended");
خروجی را تأیید کنید :
Manataz provides the most complete and specialized programming services
Program Ended
Non-Blocking Code :
یک فایل متنی با نام input.txt با محتوای زیر ایجاد کنید.
Manataz provides the most complete and specialized programming services
main.js را برای داشتن کد زیر به روز کنید :
var fs = require("fs");
fs.readFile('input.txt', function (err, data) {
if (err) return console.error(err);
console.log(data.toString());
});
console.log("Program Ended");
اکنون main.js را اجرا کنید تا نتیجه را ببینید :
$ node main.js
خروجی را تأیید کنید :
Program Ended
Manataz provides the most complete and specialized programming services
این دو مثال مفهوم تماس های blocking و non-blocking را توضیح می دهند.
مثال اول نشان می دهد که برنامه تا زمانی که فایل را بخواند blocking می کند و سپس فقط برنامه را به پایان می رساند.
مثال دوم نشان می دهد که برنامه منتظر خواندن فایل نمی ماند و اقدام به چاپ “Program Ended” می کند و در همان زمان، برنامه بدون blocking به خواندن فایل ادامه می دهد.
بنابراین، یک برنامه blocking به ترتیب بسیار زیاد اجرا می شود.
از نقطه نظر برنامه نویسی، پیاده سازی منطق آسان تر است، اما برنامه های non-blocking به ترتیب اجرا نمی شوند.
در صورتی که یک برنامه نیاز به استفاده از هر داده ای برای پردازش داشته باشد، باید در همان بلوک نگه داشته شود تا به صورت متوالی اجرا شود.
Event Emitter
بسیاری از اشیاء در یک Node ، رویدادها را منتشر می کنند ، به عنوان مثال ، یک net.Server هر بار که یک peer به آن متصل می شود یک رویداد منتشر می کند، یک fs.readStream یک رویداد را هنگامی که فایل باز می شود منتشر می کند.
تمام اشیایی که رویدادها را ساطع می کنند نمونه های EventEmitter هستند.
کلاس EventEmitter در events module قرار دارد و از طریق کد زیر قابل دسترسی است :
// Import events module
var events = require('events');
// Create an eventEmitter object
var eventEmitter = new events.EventEmitter();
هنگامی که یک نمونه EventEmitter با هر خطایی روبرو می شود ، یک رویداد “خطا” منتشر می کند.
هنگامی که یک listener جدید اضافه می شود ، رویداد “newListener” فعال می شود و هنگامی که listener حذف می شود، رویداد “removeListener” فعال می شود.
EventEmitter چندین ویژگی مانند on و emit را ارائه می دهد.
ویژگی on برای اتصال یک تابع با رویداد و emit برای فعال کردن یک رویداد استفاده می شود.
انواع متدها عبارتند از :
- addListener(event, listener)
- on(event, listener)
- once(event, listener)
- removeListener(event, listener)
- removeAllListeners([event])
- setMaxListeners(n)
- listeners(event)
- emit(event, [arg1], [arg2], […])
مثال :
یک فایل js با نام main.js با کد Node.js زیر ایجاد کنید :
var events = require('events');
var eventEmitter = new events.EventEmitter();
// listener #1
var listner1 = function listner1() {
console.log('listner1 executed.');
}
// listener #2
var listner2 = function listner2() {
console.log('listner2 executed.');
}
// Bind the connection event with the listner1 function
eventEmitter.addListener('connection', listner1);
// Bind the connection event with the listner2 function
eventEmitter.on('connection', listner2);
var eventListeners = require('events').EventEmitter.listenerCount
(eventEmitter,'connection');
console.log(eventListeners + " Listner(s) listening to connection event");
// Fire the connection event
eventEmitter.emit('connection');
// Remove the binding of listner1 function
eventEmitter.removeListener('connection', listner1);
console.log("Listner1 will not listen now.");
// Fire the connection event
eventEmitter.emit('connection');
eventListeners = require('events').EventEmitter.listenerCount(eventEmitter,'connection');
console.log(eventListeners + " Listner(s) listening to connection event");
console.log("Program Ended.");
اکنون main.js را اجرا کنید تا نتیجه را ببینید :
$ node main.js
خروجی را تأیید کنید :
2 Listner(s) listening to connection event
listner1 executed.
listner2 executed.
Listner1 will not listen now.
listner2 executed.
1 Listner(s) listening to connection event
Program Ended.
Buffer ها
جاوا اسکریپت سازگار با یونیکد است ، اما برای داده های باینری اینطور نیست.
هنگامی که با TCP streams یا file system سروکار دارید، لازم است که octet streams را مدیریت کنید.
Node کلاس Buffer را ارائه می دهد که نمونه هایی را برای ذخیره داده های خام مشابه آرایه ای از اعداد صحیح ارائه می دهد ، اما مربوط به تخصیص حافظه خام خارج از پشته V8 است.
کلاس بافر یک کلاس جهانی است که بدون وارد کردن ماژول بافر در یک برنامه قابل دسترسی است.
Node Buffer را می توان به روش های مختلفی ساخت.
روش ۱
در زیر سینتکسی برای ایجاد یک بافر آغاز نشده از 10 octets آمده است :
var buf = new Buffer(10);
روش ۲
در زیر دستور ایجاد یک بافر از یک آرایه داده شده ؛ آمده است :
var buf = new Buffer([10, 20, 30, 40, 50]);
روش ۳
در زیر دستور ایجاد یک بافر از یک رشته داده شده و نوع کدگذاری اختیاری آمده است :
var buf = new Buffer("Simply Easy Learning", "utf-8");
در زیر متد لازم برای نوشتن در Node Buffer ، آمده است :
buf.write(string[, offset][, length][, encoding])
string : این داده رشته ای است که باید در بافر نوشته شود.
offset : این شاخص بافر برای شروع نوشتن است. مقدار پیش فرض 0 است.
length : این تعداد بایت هایی است که باید بنویسید. پیشفرض به buffer.length میرسد.
encoding : رمزگذاری پیشفرض برای استفاده ‘utf8’ است.
Return Value : این متد تعداد اکاتت های نوشته شده را برمی گرداند ؛ اگر فضای کافی در بافر برای قرار دادن کل رشته وجود نداشته باشد، بخشی از رشته را می نویسد.
مثال :
buf = new Buffer(256);
len = buf.write("Simply Easy Learning");
console.log("Octets written : "+ len);
هنگامی که برنامه فوق اجرا می شود ، نتیجه زیر را ایجاد می کند :
Octets written : 20
خواندن از بافر
در زیر سینتکس خواندن داده ها از Node Buffer ، آمده است.
buf.toString([encoding][, start][, end])
Return Value
این روش یک رشته را از داده های بافر که با استفاده از کدگذاری مجموعه کاراکتر مشخص شده رمزگذاری شده است، رمزگشایی و برمی گرداند.
buf = new Buffer(26);
for (var i = 0 ; i < 26 ; i++) {
buf[i] = i + 97;
}
console.log( buf.toString('ascii')); // outputs: abcdefghijklmnopqrstuvwxyz
console.log( buf.toString('ascii',0,5)); // outputs: abcde
console.log( buf.toString('utf8',0,5)); // outputs: abcde
console.log( buf.toString(undefined,0,5)); // encoding defaults to 'utf8', outputs abcde
هنگامی که برنامه فوق اجرا می شود ، نتیجه زیر را ایجاد می کند :
abcdefghijklmnopqrstuvwxyz
abcde
abcde
abcde
اتصال بافر ها
در زیر سینتکس ، متصل کردن بافرهای Node به یک Node Buffer منفرد آمده است.
Buffer.concat(list[, totalLength])
list : لیست آرایهای از اشیاء بافر که باید الحاق شوند.
totalLength : این طول کل بافرها ، هنگام الحاق است.
مقایسه بافر ها
مثال :
var buffer1 = new Buffer('ABC');
var buffer2 = new Buffer('ABCD');
var result = buffer1.compare(buffer2);
if(result < 0) {
console.log(buffer1 +" comes before " + buffer2);
} else if(result === 0) {
console.log(buffer1 +" is same as " + buffer2);
} else {
console.log(buffer1 +" comes after " + buffer2);
}
خروجی :
ABC comes before ABCD
کپی کردن بافر ها :
buf.copy(targetBuffer[, targetStart][, sourceStart][, sourceEnd])
Streams
Streams اشیایی هستند که به شما امکان می دهند داده ها را از یک منبع بخوانید یا داده ها را به یک مقصد بنویسید.
در Node.js ، چهار نوع Stream وجود دارد :
Readable : استریمی که برای عملیات خواندن استفاده می شود.
Writable : استریمی که برای عملیات نوشتن استفاده می شود.
Duplex : استریمی که می تواند هم برای عملیات خواندن و هم برای نوشتن استفاده شود.
Transform : یک نوع جریان دوبلکس که در آن خروجی بر اساس ورودی محاسبه می شود.
هر نوع Stream یک نمونه EventEmitter است و چندین رویداد را در زمانهای مختلف ارسال میکند.
data : این رویداد زمانی فعال می شود که داده ای برای خواندن در دسترس باشد.
end ؛ این رویداد زمانی فعال می شود که داده دیگری برای خواندن وجود نداشته باشد.
error : این رویداد زمانی فعال می شود که در دریافت یا نوشتن داده ها خطایی وجود داشته باشد.
finish : این رویداد زمانی فعال می شود که تمام داده ها به سیستم زیرین منتقل شوند.
در ادامه برای خواندن و نوشتن استریم ها مثال خواهیم زد.
خواندن از یک جریان
یک فایل متنی با نام input.txt با محتوای زیر ایجاد کنید :
Manataz provides the most complete and specialized programming services
یک فایل js با نام main.js با کد زیر ایجاد کنید :
var fs = require("fs");
var data = '';
// Create a readable stream
var readerStream = fs.createReadStream('input.txt');
// Set the encoding to be utf8.
readerStream.setEncoding('UTF8');
// Handle stream events --> data, end, and error
readerStream.on('data', function(chunk) {
data += chunk;
});
readerStream.on('end',function() {
console.log(data);
});
readerStream.on('error', function(err) {
console.log(err.stack);
});
console.log("Program Ended");
اکنون main.js را اجرا کنید تا نتیجه را ببینید :
$ node main.js
تایید خروجی :
Program Ended
Manataz provides the most complete and specialized programming services
نوشتن Stream
یک فایل js با نام main.js با کد زیر ایجاد کنید :
var fs = require("fs");
var data = 'Simply Easy Learning';
// Create a writable stream
var writerStream = fs.createWriteStream('output.txt');
// Write the data to stream with encoding to be utf8
writerStream.write(data,'UTF8');
// Mark the end of file
writerStream.end();
// Handle stream events --> finish, and error
writerStream.on('finish', function() {
console.log("Write completed.");
});
writerStream.on('error', function(err) {
console.log(err.stack);
});
console.log("Program Ended");
اکنون main.js را اجرا کنید تا نتیجه را ببینید :
$ node main.js
خروجی را وریفای کنید :
Program Ended
Write completed.
اکنون output.txt ایجاد شده در فهرست فعلی شما را باز کنید.
باید شامل موارد زیر باشد :
Simply Easy Learning
File System
Node فایل ورودی/خروجی را با استفاده از wrapper های ساده پیرامون توابع استاندارد POSIX پیاده سازی می کند.
ماژول Node File System (fs) را می توان به صورت زیر استفاده کرد :
var fs = require("fs")
Synchronous در مقابل Asynchronous
هر متد در ماژول fs دارای اشکال synchronous و همچنین asynchronous است.
متدهای asynchronous آخرین پارامتر را به عنوان پاسخ به فراخوانی تابع completion و اولین پارامتر تابع callback را به عنوان خطا در نظر می گیرند.
بهتر است به جای روش synchronous از یک روش asynchronous استفاده کنید، زیرا اولی هرگز برنامه ای را در طول اجرای آن block نمی کند، در حالی که روش دوم این کار را می کند.
var fs = require("fs");
var data = '';
// Create a readable stream
var readerStream = fs.createReadStream('input.txt');
// Set the encoding to be utf8.
readerStream.setEncoding('UTF8');
// Handle stream events --> data, end, and error
readerStream.on('data', function(chunk) {
data += chunk;
});
readerStream.on('end',function() {
console.log(data);
});
readerStream.on('error', function(err) {
console.log(err.stack);
});
console.log("Program Ended");
یک فایل را مطابق با سینتکس زیر باز کنید :
fs.open(path, flags[, mode], callback)
پارامتر ها :
path : این رشته ای است که نام فایل شامل path را دارد.
flags : فلگ ها رفتار فایلی که باید باز شود را نشان می دهد.
mode : حالت فایل را تنظیم می کند، اما فقط در صورتی که فایل ایجاد شده باشد. به طور پیش فرض 0666، قابل خواندن و نوشتن است.
callback : این تابع callback است که دو آرگومان (err, fd) دریافت می کند.
دریافت اطلاعات فایل :
اجازه دهید یک فایل js با نام main.js با کد زیر ایجاد کنیم :
var fs = require("fs");
console.log("Going to get file info!");
fs.stat('input.txt', function (err, stats) {
if (err) {
return console.error(err);
}
console.log(stats);
console.log("Got file info successfully!");
// Check file type
console.log("isFile ? " + stats.isFile());
console.log("isDirectory ? " + stats.isDirectory());
});
اکنون main.js را اجرا کنید تا نتیجه را ببینید :
$ node main.js
خروجی را وریفای کنید :
Going to get file info!
{
dev: 1792,
mode: 33188,
nlink: 1,
uid: 48,
gid: 48,
rdev: 0,
blksize: 4096,
ino: 4318127,
size: 97,
blocks: 8,
atime: Sun Mar 22 2015 13:40:00 GMT-0500 (CDT),
mtime: Sun Mar 22 2015 13:40:57 GMT-0500 (CDT),
ctime: Sun Mar 22 2015 13:40:57 GMT-0500 (CDT)
}
Got file info successfully!
isFile ? true
isDirectory ? false
بستن یک فایل :
fs.close(fd, callback)
پارامتر ها :
fd : این توصیفگر فایل است که توسط متد ()fs.open بازگردانده شده است.
callback : هیچ آرگومان دیگری به جز یک استثنای ممکن برای پاسخ به تماس تکمیلی داده نشده است.
مثال :
یک فایل js با نام main.js با کد زیر ایجاد کنیم :
var fs = require("fs");
var buf = new Buffer(1024);
console.log("Going to open an existing file");
fs.open('input.txt', 'r+', function(err, fd) {
if (err) {
return console.error(err);
}
console.log("File opened successfully!");
console.log("Going to read the file");
fs.read(fd, buf, 0, buf.length, 0, function(err, bytes) {
if (err) {
console.log(err);
}
// Print only read bytes to avoid junk.
if(bytes > 0) {
console.log(buf.slice(0, bytes).toString());
}
// Close the opened file.
fs.close(fd, function(err) {
if (err) {
console.log(err);
}
console.log("File closed successfully.");
});
});
});
اکنون main.js را اجرا کنید تا نتیجه را ببینید :
$ node main.js
خروجی را وریفای کنید :
Going to open an existing file
File opened successfully!
Going to read the file
Tutorials Point is giving self learning content
to teach the world in simple and easy way!!!!!
File closed successfully.
delet یک فایل :
fs.unlink(path, callback)
مثال :
یک فایل js با نام main.js با کد زیر ایجاد کنیم :
var fs = require("fs");
console.log("Going to delete an existing file");
fs.unlink('input.txt', function(err) {
if (err) {
return console.error(err);
}
console.log("File deleted successfully!");
});
اکنون main.js را اجرا کنید تا نتیجه را ببینید :
$ node main.js
خروجی را وریفای کنید :
Going to delete an existing file
File deleted successfully!
ساخت یک دایرکتوری :
fs.mkdir(path[, mode], callback)
(mode : این مجوز دایرکتوری است که باید تنظیم شود. پیش فرض 0777 است.)
مثال :
یک فایل js با نام main.js با کد زیر ایجاد کنیم :
var fs = require("fs");
console.log("Going to create directory /tmp/test");
fs.mkdir('/tmp/test',function(err) {
if (err) {
return console.error(err);
}
console.log("Directory created successfully!");
});
خروجی را وریفای کنید :
Going to create directory /tmp/test
Directory created successfully!
خواندن یک دایرکتوری :
fs.readdir(path, callback)
حذف یک دایرکتوری :
fs.rmdir(path, callback)
Global Objects
تابع گلوبال setInterval(cb, ms) برای اجرای مکرر cb پس از حداقل ms میلی ثانیه استفاده می شود.
تاخیر واقعی به عوامل خارجی مانند OS timer granularity و system load بستگی دارد.
یک تایمر نمی تواند بیش از 24.8 روز طول بکشد.
مثال :
// Let's try to print the value of __filename
console.log( __filename );
خروجی :
$ node main.js
بر اساس مکان برنامه شما ، نام فایل اصلی را به صورت زیر چاپ می کند :
/web/com/1427091028_21099/main.js
__dirname
dirname نشان دهنده نام دایرکتوری است که اسکریپت در حال اجرای فعلی در آن قرار دارد.
مثال :
یک فایل js با نام main.js با کد زیر ایجاد کنید :
// Let's try to print the value of __dirname
console.log( __dirname );
اکنون main.js را اجرا کنید تا نتیجه را ببینید :
$ node main.js
بر اساس مکان برنامه شما، نام دایرکتوری فعلی را به صورت زیر چاپ می کند :
/web/com/1427091028_21099
بستن یک فایل :
fs.close(fd, callback)
setTimeout(cb, ms)
مثال :
function printHello() {
console.log( "Hello, World!");
}
// Now call above function after 2 seconds
setTimeout(printHello, 2000);
بررسی کنید که خروجی پس از کمی تاخیر چاپ شده است :
Hello, World!
clearTimeout(t)
function printHello() {
console.log( "Hello, World!");
}
// Now call above function after 2 seconds
var t = setTimeout(printHello, 2000);
// Now clear the timer
clearTimeout(t);
setInterval(cb, ms)
function printHello() {
console.log( "Hello, World!");
}
// Now call above function after 2 seconds
setInterval(printHello, 2000);
ایجاد وب سرور با استفاده از Node
Node.js یک ماژول http ارائه می دهد که می تواند برای ایجاد یک سرویس گیرنده HTTP از یک سرور استفاده شود.
ساختار زیر حداقل ساختار سرور HTTP است که در پورت 8081 گوش می دهد.
یک فایل js با نام server.js ، ایجاد کنید.
var http = require('http');
var fs = require('fs');
var url = require('url');
// Create a server
http.createServer( function (request, response) {
// Parse the request containing file name
var pathname = url.parse(request.url).pathname;
// Print the name of the file for which request is made.
console.log("Request for " + pathname + " received.");
// Read the requested file content from file system
fs.readFile(pathname.substr(1), function (err, data) {
if (err) {
console.log(err);
// HTTP Status: 404 : NOT FOUND
// Content Type: text/plain
response.writeHead(404, {'Content-Type': 'text/html'});
} else {
//Page found
// HTTP Status: 200 : OK
// Content Type: text/plain
response.writeHead(200, {'Content-Type': 'text/html'});
// Write the content of the file to response body
response.write(data.toString());
}
// Send the response body
response.end();
});
}).listen(8081);
// Console will print the message
console.log('Server running at http://127.0.0.1:8081/');
حال اجازه دهید فایل html زیر را با نام index.htm در همان فهرستی که server.js را ایجاد کردید ایجاد کنیم.
Sample Page
Hello World!
حالا اجازه دهید server.js را اجرا کنیم تا نتیجه را ببینیم :
$ node server.js
خروجی را تایید کنید :
Server running at http://127.0.0.1:8081/
از سرور Node.js درخواست بدهید.
http://127.0.0.1:8081/index.htm را در هر مرورگری باز کنید تا نتیجه زیر را ببینید.
خروجی را وریفای کنید :
Server running at http://127.0.0.1:8081/
Request for /index.htm received.
ایجاد وب کلاینت با استفاده از Node :
فایل Client.js
var http = require('http');
// Options to be used by request
var options = {
host: 'localhost',
port: '8081',
path: '/index.htm'
};
// Callback function is used to deal with response
var callback = function(response) {
// Continuously update stream with data
var body = '';
response.on('data', function(data) {
body += data;
});
response.on('end', function() {
// Data received completely.
console.log(body);
});
}
// Make a request to the server
var req = http.request(options, callback);
req.end();
اکنون client.js را از ترمینال فرمان دیگری غیر از server.js اجرا کنید تا نتیجه را ببینید :
$ node client.js
خروجی را وریفای کنید :
Sample Page
Hello World!
خروجی را در سمت سرور بررسی کنید :
Server running at http://127.0.0.1:8081/
Request for /index.htm received.
برای یک آشنایی با node.js به صورت جامع و کامل توضیحاتی که تا همینجا ارائه دادیم کافی است.
هدف ما از این مقاله آموزش کامل این فریمورک نیست و صد در صد به غیر از مطالعه ی این مقاله بخش های خیلی زیاد دیگری را بیاموزید.
مهرسا امینی
برنامه نویس ، انیماتور ، سئوکار
اگر در مسیری هستید که شیطان به سراغ شما نمی آید ، صد در صد در مسیر اشتباهی قرار دارید.