طراحی سایت و برنامه نویسی

آموزش طراحی سایت و برنامه نویسی

طراحی سایت و برنامه نویسی

آموزش طراحی سایت و برنامه نویسی

Overload در تابع های ++C — راهنمای کاربردی

تابع‌های Overload شده به توابعی گفته می‌شود که نامی یکسان اما آرگومان‌(های) متفاوتی دارند. در این مقاله به بررسی نمونه‌هایی از تابع‌های Overload شده می‌پردازیم. برای مطالعه بخش قبلی این مجموعه مقالات آموزشی به لینک زیر مراجعه کنید:

چنان که در بخش‌های قبلی صحبت کردیم تابع به معنی قطعه کدی است که به گروه‌بندی کد می‌پردازد و وظیفه خاصی را اجرا می‌کند. در برنامه‌نویسی ++C دو تابع به شرط این که تعداد و/یا نوع آرگومان‌هایی که ارسال می‌شوند متفاوت باشند، می‌توانند نام یکسانی داشته باشند.

در تابع‌های زیر نوع یا تعداد (و یا هر دوی) پارامترها متفاوت هستند و لذا به نام تابع‌های overload شده شناخته می‌شوند:

در قطعه کد فوق 4 تابع به صورت تابع‌های overload شده هستند، زیرا آرگومان(های) ارسالی به این تابع‌ها متفاوت هستند. توجه داشته باشید که نوع بازگشتی هر 4 تابع یکسان هستند. تابع‌های overload شده ممکن است نوع بازگشتی متفاوتی داشته باشند یا نداشته باشند، اما حتماً باید آرگومان‌های متفاوتی داشته باشند.

تعداد و نوع آرگومان‌های ارسالی به این دو تابع حتی با این که نوع بازگشتی متفاوت است، یکسان هستند. از این رو کامپایلر خطایی ایجاد می‌کند.

مثال 1

overload کردن تابع:

خروجی

Integer number: 5
Float number: 5.5
Integer number: 5 and float number: 5.5

در کد فوق، تابع ()display سه بار با انواع یا تعداد متفاوتی از آرگومان‌ها فراخوانی می‌شود. نوع بازگشتی همه این تابع‌ها یکسان است، اما الزامی برای این مسئله وجود ندارد.

مثال 2

overload کردن تابع:

خروجی

Absolute value of -5 = 5
Absolute value of 5.5 = 5.5

در مثال فوق، دو تابع ()absolute به صورت overload شده هستند. هر دو تابع آرگومان منفردی می‌گیرند. با این حال، یک تابع مقدار integer به عنوان آرگومان می‌گیرد و آرگومان دیگر از نوع float است. زمانی که تابع ()absolute با یک آرگومان integer فراخوانی شود، این تابع فراخوانی می‌شود:

اما زمانی که تابع ()absolute با یک آرگومان float فراخوانی شود، تابع زیر فراخوانی می‌شود:

بدین ترتیب به پایان این بخش از سری مقالات آموزش زبان برنامه‌نویسی ++C می‌رسیم.


منبع: فرادرس

آموزش Node.js: ماژول http — راهنمای جامع

ماژول http در Node.js تابع‌ها و کلاس مفیدی برای ساختن سرور HTTP ارائه می‌کند. در واقع یک ماژول کلیدی Node.js برای شبکه محسوب می‌شود. در این نوشته به بررسی کارکردهای مختلف این ماژول می‌پردازیم. برای مطالعه بخش قبلی این مجموعه مقالات آموزشی به لینک زیر رجوع کنید:

شما می‌توانید با استفاده از دستور زیر این ماژول را در فایل خود include کنید:

ماژول مورد اشاره برخی مشخصه‌ها و متدها و همچنین برخی کلاس‌ها را ارائه می‌کند.

مشخصه‌ها

در این بخش به بررسی مشخصه‌های ماژول http می‌پردازیم.

http.METHODS

این مشخصه لیستی از همه متدهای مورد پشتیبانی HTTP را ارائه می‌کند:

http.STATUS_CODES

این مشخصه همه کدهای حالت HTTP و توصیف آن‌ها را لیست می‌کند:

http.globalAgent

این مشخصه به وهله‌ای سراسری از شیء Agent اشاره می‌کند که وهله‌ای از کلاس http.Agent است. این مشخصه به مدیریت اتصال‌های دائمی می‌پردازد و از آن‌ها برای کلاینت‌های HTTP استفاده مجدد می‌کند و مؤلفه‌ای کلیدی برای شبکه‌بندی HTTP در Node.js محسوب می‌شود. برای مشاهده توضیحات بیشتر در خصوص http.Agent به ادامه همین مقاله مراجعه کنید.

متدها

در این بخش متدهای موجود در ماژول http را معرفی می‌کنیم.

()http.createServer

این متد یک وهله از کلاس http.Server بازگشت می‌دهد. کاربرد آن به صورت زیر است:

()http.request

یک درخواست HTTP به سرور ایجاد می‌کند و وهله‌ای از کلاس http.ClientRequest می‌سازد.

()http.get

مشابه ()http.request است، اما به صورت خودکار متد HTTP را روی GET تنظیم می‌کند و ()req.end را به صورت خودکار فراخوانی می‌کند.

کلاس‌ها

ماژول HTTP پنج کلاس ارائه می‌کند که در ادامه به آن‌ها می‌پردازیم:

کلاس http.Agent

Node وهله‌ای سراسری از کلاس http.Agent برای مدیریت تداوم اتصال و استفاده مجدد از کلاینت‌های HTTP ارائه می‌کند که مؤلفه‌ای کلیدی برای شبکه‌بندی HTTP محسوب می‌شود. بدین ترتیب مطمئن می‌شویم که هر درخواست که به سرور ارسال می‌شود صف‌بندی شده و یک سوکت منفرد مورد استفاده مجدد قرار می‌گیرد. همچنین یک استخر از سوکت‌ها نگهداری می‌کند که برای حفظ عملکرد مؤلفه‌ای کلیدی محسوب می‌شود.

کلاس http.ClientRequest

هر شیء http.ClientRequest زمانی که ()http.request یا ()http.get فراخوانی می‌شود، ایجاد خواهد شد. زمانی که پاسخی دریافت می‌شود، رویداد response با استفاده از پاسخ فراخوانی می‌شود و آرگومان آن نیز وهله‌ای از http.IncomingMessage است.

در مورد داده‌های بازگشتی یک پاسخ را می‌توان به 2 روش خواند:

  • می‌توان متد ()response.read را فراخوانی کرد.
  • همچنین می‌توان در دستگیره رویداد response یک شنونده رویداد برای رویداد date تنظیم کرد و بدین ترتیب به داده‌هایی که وارد می‌شوند توجه کرد.

کلاس http.Server

این کلاس به طور معمول زمانی وهله‌سازی و بازگشت داده می‌شود که یک سرور جدید با استفاده از ()http.createServer ساخته می‌شود.

زمانی که یک شیء سرور دارید، به متدهای آن نیز دسترسی دارید:

  • ()Close سرور را از پذیرش اتصال‌های جدید باز می‌دارد.
  • ()Listen موجب می‌شود که سرور HTTP آغاز شده و به اتصال‌ها گوش دهد.

کلاس http.ServerResponse

این کلاس به وسیله http.Server ساخته شده است و به عنوان پارامتر دوم به رویداد request ارسال می‌شود. این کلاس به طور معمول در کد به صورت res نوشته و استفاده می‌شود:

متدی که معمولاً در دستگیره فراخوانی می‌شود ()end نام دارد که موجب بسته شدن response می‌شود و بدین ترتیب با کامل شدن پیام، سرور می‌تواند آن را به کلاینت بفرستد. آن را باید روی هر پاسخ فراخوانی کرد.

از این متدها برای تعامل با هدرهای HTTP استفاده می‌شود:

  • ()getHeaderNames – لیستی از نام‌های هدرهای HTTP که از قبل تعیین شده را بازگشت می‌دهد.
  • ()getHeaders – یک کپی از هدرهای HTTP که قبلاً تعیین شده‌اند به دست می‌دهد.
  • (setHeader(‘headername’, value – یک مقدار هدر HTTP را تنظیم می‌کند.
  • (‘getHeader(‘headername – یک هدر HTTP را که قبلاً تنظیم شده دریافت می‌کند.
  • (‘removeHeader(‘headername – یک هدر HTTP که قبلاً تنظیم‌شده را حذف می‌کند.
  • (‘hasHeader(‘headername – در صورتی که پاسخ دارای هدر تعیین شده باشد، مقدار true بازگشت می‌دهد.
  • ()headersSent – در صورتی که هدرها از قبل به کلاینت ارسال شده باشند، مقدار true بازگشت می‌دهد.

پس از پردازش هدرها می‌توان آن‌ها را مستقیماً با فراخوانی ()response.writeHead به کلاینت ارسال کرد. این متد یک statusCode به عنوان پارامتر اول می‌گیرد و پیام وضعیت و شیء هدر نیز اختیاری هستند.

برای ارسال داده‌ها به کلاینت در بدنه پاسخ باید از متد ()write استفاده کنید. این متد داده‌های بافر شده را به استریم پاسخ HTTP می‌فرستد.

اگر هدرها با استفاده از ()response.writeHead ارسال نشده باشند، ابتدا به همراه کد وضعیت و پیام آن که در درخواست تنظیم شده فرستاده می‌شوند. این موارد را می‌توانید با تنظیم مقادیر مشخصه‌های statusCode و statusMessage تغییر دهید.

کلاس http.IncomingMessage

یک شیء http.IncomingMessage به صورت زیر ساخته می‌شود:

  • http.Server زمانی که به رویداد request گوش می‌دهد.
  • http.ClientRequest زمانی که به رویداد response گوش می‌دهد.

از این کلاس می‌توان برای دسترسی به اجزای پاسخ به صورت زیر استفاده کرد:

  • برای دسترسی به وضعیت می‌توان از متدهای statusCode و statusMessage آن استفاده کرد.
  • برای دسترسی به هدرها می‌توان از متد headers یا rawHeaders استفاده کرد.
  • متد HTTP با استفاده از متدی به نام method مورد دسترسی قرار می‌گیرد.
  • نسخه HTTP با استفاده از متد httpVersion به دست می‌آید.
  • URL با استفاده از متد url به دست می‌آید.
  • سوکت زیرین با استفاده از متد socket به دست می‌آید.

این داده‌ها با استفاده از استریم‌ها در دسترس ما قرار می‌گیرند، زیرا http.IncomingMessage اینترفیس Readable Stream را پیاده‌سازی می‌کند.

بدین ترتیب به پایان این بخش از سری مقالات آموزش Node.js می‌رسیم.

اگر

منبع: فرادرس

توسعه اپلیکیشن های تلفن‌ های هوشمند — از ایده تا اجرا

تصور کنید ایده‌ای عالی برای ساخت یک اپلیکیشن برای گوشی‌های هوشمند دارید و می‌خواهید بدانید که چگونه باید شروع به این کار بکنید؟ در این مقاله با شیوه ساخت یک اپلیکیشن و تبدیل ایده به محصول نهایی آشنا می‌شوید، به طوری که افراد مختلف می‌توانند اپلیکیشن شما را از اپ‌استور اپل یا پلی‌استور گوگل دانلود کنند. در ادامه با مراحل طراحی یک اپلیکیشن آشنا خواهیم شد.

در این نوشته با اهمیت ضروری تحقیق آشنا می‌شویم و این نکته را روشن می‌سازیم که چرا باید در مورد مفهوم اپلیکیشن خود شور و اشتیاق داشته باشید. همچنین به شما کمک می‌کنیم که مهارت‌های مختلف مورد نیاز برای موفقیت را بیاموزید و مفاهیم ارزشمندی که می‌توانید برای ساخت تجربه کاربری اپلیکیشنتان مورد استفاده قرار دهید را می‌شناسیم.

تحقیق در مورد کاربران

اغلب افراد در نخستین گام وسوسه می‌شوند که مستقیماً شروع به تفکر در مورد روش ساخت اپلیکیشن بکنند، اما همواره باید مسیر توسعه اپلیکیشن را با به دست آوردن ایده‌ای روشن از هدف خود آغاز کنید. برای این که بدانید معنی این حرف چیست، باید در مورد کاری که اپلیکیشنتان انجام می‌دهد، ایده روشنی داشته باشید، همچنین بدانید که کاربران اپلیکیشن شما چه کسانی هستند و به چه صورت از اپلیکیشن شما استفاده خواهند کرد. بدین ترتیب باید این سؤال‌ها را از خودتان بپرسید:

  • اپلیکیشن ما چه مشکلی را قرار است حل کند؟
  • تعامل‌های ضروری کاربر کدام هستند؟
  • محتوایی که واقعاً به کار کاربران می‌آید چیست؟
  • چه چیزی باعث می‌شود که کاربران در آینده برای کسب موارد بیشتر دوباره به اپلیکیشن مراجعه کنند؟

این نوع از تحقیق به معنی صحبت کردن با افراد مختلف و بررسی نظرات آن‌ها در مورد ایده اپلیکیشن است. گرچه این کار ممکن است ملال‌آور به نظر برسد، اما لازم نیست نگران باشید، چون شما یک شرکت بزرگ نیستید که نیاز به مصاحبه با هزاران نفر داشته باشید، صحبت کردن با دوستان، خانواده، همکاران، و یا همکلاس‌ها نیز در این خصوص به قدر کافی مفید است.

بررسی رقبا

همچنین باید در مورد اپلیکیشن‌هایی که اپ شما با آن‌ها رقابت خواهد کرد نیز تحقیق کنید. کاوش پلی‌استور یا اپ‌استور برای یافتن اپلیکیشن‌هایی که کاری مشابه ایده محصول شما انجام می‌دهند به این منظور مفید خواهد بود. این اپلیکیشن‌ها را روی گوشی خود دانلود کنید تا بتوانید کاری که اجرا می‌کنند را تحلیل کرده و قابلیت‌هایی که ارائه می‌دهند را مورد بررسی قرار دهید. از خود بپرسید آیا اپلیکیشن‌های مربوطه وظایفی که در نظر دارند را با موفقیت اجرا می‌کنند و اگر چنین است ایده آن‌ها با مفهومی که شما در ذهن خود دارید چه نسبتی دارد؟ درک اپلیکیشن‌های رقیب به شما کمک می‌کند که ارزش‌های خاص اپلیکیشن خود را درک کنید. بدین ترتیب می‌توانید در صورت نیاز ایده‌های خود را طوری اصلاح کنید که کاربران، خدماتی که شما ارائه می‌کنید را جای دیگری نتوانند پیدا کنند.

نکته مهم: اگر نمی‌خواهید منحصربه‌فرد باشید، در این صورت باید بهتر از رقبا باشید.

ایجاد تجربه کاربری عالی

هر زمان که از یک اپلیکیشن محبوب خود استفاده می‌کنید، تلاش کنید با دیدی تحلیلی به بررسی آن چه موجب جذب شما به آن شده است نگاه کنید. آیا محتوای آن به خوبی سازمان‌دهی یافته است؟ آیا طراحی آن روی گوشی شما عالی به نظر می‌رسد. آیا از سرعت کارکرد آن تحت تأثیر قرار می‌گیرید؟ با چند ضربه روی صفحه گوشی می‌توانید هدف مورد نظر خود را اجرا کنید؟ آیا امکاناتی وجود دارند که هرگز استفاده نکرده‌اید؟ آیا فکر می‌کنید طراحی آن تکیه زیادی روی متن دارد؟ چنین تفکرهای نقادانه‌ای می‌تواند به ایجاد درکی از شیوه ایجاد تجربه کاربری اپلیکیشن خودتان کمک کند.

چرا باید مشتاق باشید؟

بسیار مهم است در مورد پروژه‌ای که برای ساخت انتخاب می‌کنید از آغاز اشتیاق داشته باشید. نخستین اپلیکیشن شما نیاز به تعهد کاری بالا دارد و این که انرژی شما در طول پروژه نوسان داشته باشد، کاملاً طبیعی است اما کار کردن روی چیزی که در مورد آن اشتیاق دارید موجب خواهد شد که متمرکز بمانید و برای به پایان رساندن پروژه انگیزه کافی داشته باشید.

مراحل طراحی یک اپلیکیشن

کسب مهارت‌های مناسب

همه کارهای مفهومی که تا به اینجا صحبت کردیم برای موفقیت یک محصول کاملاً ضروری هستند، اما این‌ها تنها بخشی از چالش هستند. شما باید دانش فنی مناسبی نیز برای حیات بخشیدن به ایده خود داشته باشید. بسته به مهارت‌ها و تجربه فعلی‌تان ممکن است لازم باشد پیش از آغاز عملی کار ساخت اپلیکیشن نیاز به آموختن مواردی داشته باشید. فرادرس بازه گسترده‌ای از دوره‌های آموزش ویدئویی و مجموعه مقالات متنی برای آموزش شما ارائه کرده است. برای نمونه می‌توانید از آموزش‌های زیر برای کسب مهارت مورد نیاز جهت توسعه اپلیکیشن خودتان کمک بگیرید:

از جمله آموزش‌هایی هستند که می‌توانید برای ساخت اپلیکیشن برای پلتفرم‌های مختلف مورد استفاده قرار دهید. شما با مطالعه این آموزش‌ها می‌توانید با مهارت‌های اساسی مورد نیاز برای ساخت اپلیکیشن آشنا شوید و همچنین احیاناً مهارت‌هایی که برای ساخت اپلیکیشن برای محیط اندروید و iOS ندارید را بشناسید.

کدام مهارت‌ها را بیاموزیم؟

یک رویکرد مفید که می‌توان برای توسعه مهارت‌های برنامه‌نویسی مورد استفاده قرار دارد، این است که مجموعه مهارت‌های خود را مورد بررسی قرار دهید و مهارت‌های جدیدی که باید یاد بگیرید را شناسایی کنید. به این منظور یک کاغذ بردارید و دو ستون روی آن رسم کنید. در ستون اول همه مهارت‌های کنونی خود را لیست کنید. در ستون دوم همه مهارت‌هایی را بنویسید که فکر می‌کنید باید برای رسیدن به هدف کسب کنید. این مهارت‌ها بر مبنای آن چه که تاکنون از توسعه اپلیکیشن آموخته‌اید، قابل شناسایی خواهند بود. زمانی که این کار را انجام دادید، مهارت‌های مشترک دو ستون را خط بزنید و آنچه باقی می‌ماند مهارت‌هایی هستند که برای تبدیل ایده اپلیکیشن به واقعیت باید بیاموزید. زمانی که مهارت‌های مورد نیاز برای یادگیری را شناسایی کردید، تنها گام بعدی این است که مسیر یادگیری صحیحی را انتخاب کنید.

واقع‌گرایی در مورد مهارت‌های کنونی بسیار حائز اهمیت است، چون این که کدام تجربه یادگیری برای شما مؤثرتر است و کدام چارچوب زمانی را برای توسعه اپلیکیشن خود در نظر دارید می‌تواند تفاوت مهمی ایجاد کند.

ساده برخورد کنید

زمانی که از مهارت‌های جدید و تحقیقات میدانی برای خلق اپلیکیشن خود استفاده می‌کنید، باید همواره به خاطر داشته باشید که طراحی نهایی باید در حد امکان ساده و متمرکز باشد. تحقیق شما باید عواملی که کاربران شما مهم‌تر می‌پندارند را مشخص سازد. برای نمونه اگر یک مشکل اساسی وجود دارد که کاربران انتظار دارند اپلیکیشن شما حل کند، باید صرفاً روی آن مسئله متمرکز شوید. اگر کاربران بر این باورند که یک عنصر از بازی سرگرم‌کننده‌تر است، کانون توجه خود را روی آن متمرکز کنید. این رویکرد بدان معنی است که از صرف زمان ارزشمند توسعه روی قابلیت‌هایی که برای کاربران اهمیت ندارد اجتناب می‌کنید.

در جستجوی پشتیبانی باشید

توسعه اپلیکیشن در مراحل اولیه می‌تواند آزمونی واقعی از میزان تعهد، صبر و توانایی‌های شما باشد، بنابراین ایده جستجوی پشتیبانی برای این که متمرکز باشید و از مسیر خارج نشوید بسیار مهم است. اگر امکان دارید بهتر است از کمک‌های یک مربی کمک بگیرید که شما را راهنمایی و هدایت کند. فورورم‌های برنامه‌نویسی نیز منبع جالبی از توصیه‌های برنامه نویسان دیگر هستند که در زمان مواجهه با مشکل‌های مشابه یا نیاز به ایده‌های جدید بیشتر در حوزه‌های مختلف به کار می‌آیند.

مربی‌ها و همتایان این نکته را به شما یادآوری می‌کنند که فرایند ساخت اپلیکیشن یک تجربه یادگیری است. حتی در مراحل مقدماتی ممکن است به سادگی درگیر جزییات گیج‌کننده توسعه اپلیکیشن شوید. بنابراین اگر حتی به چالش‌برانگیزترین لحظه‌های کار به عنوان بخشی از مسیر توسعه خود بنگرید، بسیار به حفظ انگیزه شما کمک می‌کند.

مراحل طراحی یک اپلیکیشن

سخن پایانی

اکنون زمان آن رسیده که دانش خود را به صورت عملی مورد استفاده قرار دهید؛ به زبان ساده‌تر، حالا شما ابزارهای لازم برای تبدیل ایده خود به یک اپلیکیشن تلفن‌های هوشمند را در اختیار دارید. با در ذهن داشتن ایده‌ای که در مورد آن مشتاق هستید، پیاده‌سازی یک طراحی مناسب برای این ایده بر مبنای تحقیق از کاربران و در کنار هم قرار دادن مهارت‌های صحیح به یقین هیچکس بهتر از شما نمی‌تواند اپلیکیشنی که در ذهن خود به آن فکر می‌کنید را توسعه دهد. همین امروز شروع کنید تا در آینده‌ای نزدیک همگان را شگفت‌زده کنید.


منبع: فرادرس

آموزش Node.js: برنامه نویسی ناهمگام و Callback — بخش هفتم

جاوا اسکریپت به صورت پیش‌فرض یک زبان برنامه‌نویسی همگام و تک نخی است. این بدان معنی است که کد نمی‌تواند نخ‌های جدیدی ایجاد کرده و به صورت موازی اجرا شود. در این مقاله به بررسی روش‌های مختلف برنامه نویسی ناهمگام در محیط Node.js می‌پردازیم. برای مطالعه بخش قبلی این سری مقالات به لینک زیر رجوع کنید:

ناهمگامی در زبان‌های برنامه‌نویسی

رایانه‌ها اساساً دارای طراحی ناهمگام هستند. منظور از ناهمگامی این است که کارهای مختلف می‌توانند در گردش برنامه اصلی مستقل از هم اتفاق بیفتند. در رایانه‌های امروز هر برنامه‌ای برای مدت زمان معینی اجرا می‌شود و سپس اجرای آن متوقف می‌شود تا برنامه دیگری بتواند به اجرای خود ادامه بدهد. این کار در چنان چرخه سریعی اتفاق می‌افتد که کاربر هرگز متوجه نمی‌شود و ما فکر می‌کنیم رایانه ما می‌تواند به طور همزمان برنامه‌های زیادی را اجرا کند، اما این یک توهم است (البته قضیه در پردازنده‌های چندهسته‌ای متفاوت است).

برنامه‌ها به صورت داخلی از «وقفه» (interrupt) استفاده می‌کنند. وقفه یک سیگنال است که به سمت پردازنده ارسال می‌شود تا توجه سیستم را کسب کند. پرداختن به جزییات این موضوع خارج از موضوع این مقاله است؛ اما باید به خاطر داشته باشید که ناهمگامی در برنامه‌ها امری معمول است و به طور نرمال برنامه‌ها، اجرای خود را متوقف می‌کنند تا زمانی که پردازنده به آن‌ها وقتی اختصاص بدهد. زمانی که یک برنامه منتظر پاسخی از سوی شبکه است، نمی‌تواند پردازنده را معطل خود نگه دارد تا درخواست پایان یابد.

به طور معمول زبان‌های برنامه‌نویسی همگام هستند. برخی از آن‌ها نیز در حد زبان یا کتابخانه‌های جانبی، روش‌هایی برای مدیریت ناهمگامی ارائه می‌کنند. زبان‌های C ،Java ،C# ،PHP ،Go ،Ruby ،Swift و Python همگی به صورت پیش‌فرض همگام هستند. برخی از این زبان‌ها با استفاده از نخ‌ها به صورت ناهمگام عمل می‌کنند و می‌توانند یک پردازش جدید ایجاد کنند.

جاوا اسکریپت

زبان برنامه‌نویسی جاوا اسکریپت نیز به صورت پیشفرض همگام و تک نخی است. این بدان معنی است که کد نمی‌تواند نخ‌های جدید ایجاد کرده و به صورت موازی اجرا شود. در این حالت، خطوط مختلف کد یکی پس از دیگری و به ترتیب اجرا می‌شوند. برای نمونه:

اما می‌دانیم که جاوا اسکریپت درون مرورگر تولد یافته است و وظیفه اصلی آن در ابتدا پاسخ دادن به واکنش‌های کاربر مانند onClick ،onMouseOver ،onChange ،onSubmit و غیره بوده است. چنین فرایندی در یک مدل برنامه‌نویسی همگام چگونه ممکن است؟

پاسخ در محیط برنامه‌نویسی این زبان است. مرورگر روشی برای ارائه یک مجموعه از API-ها دارد که می‌توانند این نوع کارکرد را مدیریت کنند. در سال‌های اخیر Node.js یک محیط غیر مسدودکننده I/O معرفی کرده است که این مفهوم را به دسترسی فایل‌ها، فراخوانی‌های شبکه و موارد مشابه گسترش داده است.

Callback-ها

ما هرگز نمی‌دانیم که یک کاربر چه زمانی روی یک دکمه کلیک خواهد کرد، بنابراین باید یک «دستگیره رویداد» (event handler) برای رویداد کلیک تعریف کنیم.

این دستگیره رویداد تابعی قبول می‌کند که هنگام اتفاق افتادن رویداد فراخوانی می‌شود:

این همان callback مشهور است. در واقع callback تابع ساده‌ای است که به صورت یک مقدار به تابع دیگر ارسال می‌شوند و تنها زمانی اجرا خواهد شد که رویدادی اتفاق بیفتد. ما این کار را به این دلیل می‌توانیم اجرا کنیم که جاوا اسکریپت تابع‌های درجه نخست دارد که می‌توانند به متغیرها انتساب یافته و به تابع‌های دیگر (که تابع‌های درجه بالا نامیده می‌شوند) ارسال شوند.

رویه معمول این است که کد کلاینت در یک شنونده رویداد load در شیء window قرار می‌گیرد و تابع callback را در زمان آماده شدن صفحه اجرا می‌کند:

Callback-ها در همه جا استفاده می‌شوند و اختصاص به رویدادهای DOM ندارند. یک مثال عمومی استفاده از تایمر است:

درخواست‌های XHR نیز یک callback می‌پذیرند. در مثال زیر یک تابع به مشخصه‌ای که در زمان رخداد اتفاق خاص فراخوانی می‌شود، انتساب خواهد یافت:

مدیریت خطا در Callback-ها

یکی از رایج‌ترین راهبردها برای مدیریت خطا در callback-ها کاری است که Node.js انجام می‌دهد. پارامتر اول در هر تابع callback شیء خطا است که به نام callback-های error-first شناخته می‌شوند.

اگر خطایی وجود نداشته باشد، این شیء null خواهد بود. اگر خطایی رخ داده باشد این پارامتر نوعی توضیح در مورد خطا و اطلاعات مرتبط ارائه می‌کند.

مشکل Callback-ها

Callback-ها در استفاده‌های ساده بسیار عالی هستند. اما هر Callback یک سطح به سلسله‌مراتب تودرتو اضافه می‌کند. زمانی که Callback-های زیادی وجود داشته باشند، کد به سرعت پیچیده می‌شود:

این کد صرفاً 4 سطح ساده دارد، اما در موارد زیادی سطوح بسیار بیشتری از کد تودرتو را مشاهده می‌کنیم که جالب نیست. برای حل این مشکل چه باید کرد؟

جایگزین‌های Callback-ها

از ES6 به بعد جاوا اسکریپت چند قابلیت معرفی کرده است که به کدنویسی ناهمگام بدون استفاده از Callback-ها کمک می‌کند:

  • Promises (ES6)
  • Async/Await (ES8)

Promise-ها

Promise-ها یک روش برای اجرای کد ناهمگام در جاوا اسکریپت محسوب می‌شوند و با استفاده از آن‌ها دیگر لازم نیست نگران وجود Callback-های زیاد در کد باشیم.

مقدمه‌ای بر Promise-ها

یک Promise عموماً به صورت واسطی برای یک مقدار تعریف می‌شود که در زمانی در آینده موجود خواهد شد. با این که سال‌هاست Promise-ها معرفی شده‌اند اما صرفاً در ES2015 استاندارد و معرفی شدند و هم اکنون در ES2017 با معرفی تابع‌های async منسوخ گشته‌اند. تابع‌های async از API مربوط به Promise ها به عنوان بلوک‌های سازنده خود استفاده می‌کند و از این رو درک آن‌ها حتی در صورتی که بخواهید در کد خود از تابع‌های async به جای promise استفاده کنید ضروری خواهد بود.

طرز کار Promise-ها به طور خلاصه

زمانی که یک Promise فراخوانی می‌شود در «حالت انتظار» (pending state) کار خود را آغاز می‌کند. این بدان معنی است که تابع فراخواننده به اجرای خود ادامه می‌دهد در حالی که منتظر Promise است تا پردازش‌های خودش را اجرا کند و بازخوردی به تابع فراخواننده بدهد.

در این زمان تابع فراخواننده منتظر آن می‌ماند تا Promise را در «حالت حل شده» (resolved state) یا در «حالت رد شده» (rejected state) بازگشت دهد، اما چنان که می‌دانید جاوا اسکریپت همگام است و از این رو در زمانی که Promise کار نمی‌کند، تابع همچنان به اجرای خود ادامه می‌دهد.

کدام API جاوا اسکریپت از Promise-ها استفاده می‌کند؟

علاوه بر کد کاربر و کد کتابخانه‌های مختلف، Promise-ها از سوی API-های مدرن استاندارد وب مانند لیست زیر نیز مورد استفاده قرار می‌گیرند:

  • Battery API
  • Fetch API
  • Service Workers

این که در جاوا اسکریپت مدرن از Promise-ها استفاده نکنید امر بسیار نامحتملی است، بنابراین در ادامه به بررسی دقیق‌تر آن‌ها می‌پردازیم.

ایجاد یک Promise

API مربوط به Promise یک سازنده Promise عرضه می‌کند که با استفاده از ()new Promise مقداردهی اولیه می‌شود:

چنان که می‌بینید Promise ثابت سراسری done را بررسی می‌کند و اگر درست باشد، یک Promise حل شده و در غیر این صورت Promise رد شده بازگشت می‌یابد. ما با استفاده از resolve و reject می‌توانیم یک مقدار را بازگشت دهیم. در حالت فوق ما صرفاً یک رشته بازگشت می‌دهیم اما می‌توان یک شیء را نیز بازگشت داد.

مصرف کردن یک Promise

در بخش قبلی، با روش ایجاد شدن یک Promise آشنا شدیم. اکنون به بررسی شیوه مصرف یا استفاده شدن یک Promise می‌پردازیم:

اجرای ()checkIfItsDone موجب اجرا شدن یک Promise به نام ()isItDoneYet می‌شود که منتظر حل شدن با استفاده از Callback-ی به نام then باقی می‌ماند و اگر خطایی رخ دهد آن را در callback با نام catch مدیریت می‌کند.

زنجیره‌سازی Promise-ها

هر Promise می‌تواند به Promise دیگری بازگشت یابد و یک زنجیره از Promise-ها تشکیل دهد. مثالی عالی از زنجیره‌سازی Promise-ها در API با نام Fetch مشاهده می‌شود که یک لایه فوقانی روی API مربوط به XMLHttpRequest است و می‌توان از آن برای ایجاد یک منبع و صف‌بندی یک زنجیره از Promise-ها برای اجرا در زمان واکشی شدن منبع استفاده کرد.

API با نام Fetch یک سازوکار مبتنی بر Promise است به طوری که فراخوانی ()fetch معادل تعریف کردن یک Promise با استفاده از ()new Promise است.

نمونه‌ای از زنجیره‌سازی Promise-ها

در این مثال، ()fetch را فراخوانی می‌کنیم تا فهرستی از آیتم‌های TODO را از فایل todos.json که در ریشه دامنه قرار دارد به دست آوریم و بنابراین یک زنجیره از Promise-ها ایجاد کرده‌ایم.

اجرای ()fetch موجب بازگشت یک response می‌شود که مشخصه‌های زیادی دارد، اما دو مورد از آن‌ها برای ما مهم هستند:

  • Status – یک مقدار عددی است که کد وضعیت HTTP را نشان می‌دهد.
  • statusText – یک پیام وضعیت است که در صورت موفق بودن درخواست، مقدار آن OK خواهد بود.

response یک متد ()json نیز دارد که یک Promise بازگشت می‌دهد و در آن به بررسی محتوای متنی پردازش شده و تبدیل آن به JSON می‌پردازد. با توجه به Promise-های فوق روند رویدادها به این صورت است که Promise اول در زنجیره، تابعی است که ما تعریف کرده‌ایم و آن را ()status می‌نامیم. این Promise وضعیت پاسخ را بررسی می‌کند و در صورتی که پاسخ موفق (کد بین 200 تا 299) نباشد، Promise را رد می‌کند.

این عملیات موجب می‌شود که زنجیره Promise همه Promise-های بعدی لیست شده را رد کند و مستقیماً به گزاره ()catch در انتهای کد برسد و متن Request failed را به همراه پیام خطا لاگ کند. اما اگر Promise اول موفق باشد، تابع ()json را که تعریف کرده‌ایم، فراخوانی می‌کند. از آنجا که Promise قبلی در صورت موفقیت، شیء response را بازگشت داده است، می‌توانیم آن را به عنوان ورودی به Promise دوم بدهیم.

در این حالت، داده‌های JSON پردازش شده را بازگشت می‌دهیم تا Promise سوم مستقیماً JSON را دریافت کند:

در نهایت آن را در کنسول لاگ می‌کنیم.

مدیریت خطاها

در مثال بخش قبلی، یک catch داشتیم که به زنجیره Promise-ها الصاق می‌شد. هر زمان که جزئی از زنجیره Promise-ها ناموفق باشد و خطایی رخ دهد یا یک Promise رد شود، کنترل به گزاره ()catch در انتهای زنجیره می‌رسد.

یا

آبشار سازی خطاها

اگر درون ()catch خطایی رخ دهد، می‌توان یک ()catch دیگر برای مدیریت آن الصاق کرد و این روند همین طور تا انتها ادامه می‌یابد:

هماهنگ‌سازی Promise-ها

در این بخش به روش هماهنگ کردن چند Promise می‌پردازیم.

()Promise.all

اگر لازم است که Promise-های مختلف را با یکدیگر هماهنگ کنید، می‌توانید از متد ()Promise.all برای تعریف کردن لیستی از Promise-ها استفاده کنید و زمانی که همه آن‌ها حل شدند، تابع دیگری را اجرا کنید.

مثالی از آن به صورت زیر است:

ساختار destructuring assignment در ES2015 نیز اجازه اجرای چنین کاری را می‌دهد:

البته شما محدود به استفاده از fetch نیستید و می‌توانید از هر Promise دیگری نیز استفاده کنید.

()Promise.race

این متد زمانی اجرا می‌شود که اولین Promise که به آن ارسال کرده‌اید حل شود و callback الصاق شده به آن را یک بار به همراه نتیجه نخستین Promise حل شده اجرا می‌کند. مثالی از آن به صورت زیر است:

یک خطای رایج

اگر با خطای زیر در کنسول مواجه شدید:

Uncaught TypeError: undefined is not a promise

ابتدا باید اطمینان حاصل کنید که به جای ()Promise از ()new Promise استفاده کرده‌اید.

Async و Await

جدیدترین رویکرد به تابع‌های ناهمگام در جاوا اسکریپت Async و Await است. جاوا اسکریپت در طی مدت بسیار کوتاهی (ES2015) استفاده از Callback را کنار گذاشت و به بهره‌گیری از Promise-ها روی آورد. از نسخه ES2017 نیز کدهای ناهمگام در جاوا اسکریپت با استفاده از ساختار async/await ساده‌تر شده‌اند.

تابع‌های async ترکیبی از Promise-ها و generatos-ها هستند و اساساً لایه بالاتری از تجرید نسبت به Promise محسوب می‌شوند. در اینجا باید یک بار دیگر تکرار کنیم که async/await بر مبنای Promise-ها ساخته شده‌اند.

Async/Await چرا معرفی شد؟

تابع‌های Async/Await باعث کاهش حجم کد مورد نیاز برای نوشتن Promise-ها می‌شوند و محدودیت «عدم قطع زنجیره» Promise-های زنجیره‌سازی را نیز مرتفع می‌سازند. زمانی که Promise-ها در نسخه ES2015 معرفی شدند، هدف از ارائه آن‌ها حل مشکلی در کدنویسی ناهمگام بود و در این کار نیز موفق بودند، اما در طی دو سال که بین عرضه نسخه‌های ES2015 و ES2017 وجود داشت مشخص شد که Promise-ها نمی‌توانند راه‌حل نهایی باشند.

Promise-ها برای حل مشکل مشهور جهنم callback-ها عرضه شدند، اما آن‌ها نیز پیچیدگی خاص خود را داشتند و از نظر کاربران دارای ساختار پیچیده‌ای بودند. Promise-ها با این کارکرد که به ما نشان دادند می‌توان از ساختار مناسب‌تری به این منظور استفاده کرد مفید بودند و لذا اینک زمانی فرا رسیده است که از تابع‌های async استفاده کنیم. تابع‌های async/await موجب می‌شوند کد همگام به نظر برسد، اما اساساً ناهمگام است و در پشت صحنه به روشی غیر مسدودکننده عمل می‌کند.

طرز کار Async/Await چگونه است؟

تابع async یک Promise بازگشت می‌دهد. به مثال زیر توجه کنید:

زمانی که بخواهیم این تابع را فراخوانی کنیم یک await آماده می‌کنیم و کد فراخوانی کننده متوقف می‌شود تا این که Promise حل یا رد شود. تنها الزام این است که تابع کلاینت باید به صورت async تعریف شود. به مثال زیر توجه کنید:

یک مثال ساده

در مثال ساده زیر از async/await برای اجرای ناهمگام یک تابع استفاده شده است:

کد فوق عبارت زیر را در کنسول مرورگر نمایش می‌دهد:

BeforeAfterI did something //after 3s

Promise کردن همه چیز

الصاق کردن کلیدواژه async به هر تابعی به این معنی است که تابع یک Promise بازگشت خواهد داد. حتی اگر این کار به طور صریح انجام نشده باشد، این کار موجب می‌شود که تابع به صورت درونی یک Promise بازگشت دهد. به همین دلیل است که کد زیر معتبر است:

این کد نیز مانند کد فوق است:

خواندن این کد کاملاً آسان‌تر است

چنان که در مثال فوق می‌بینیم، کد ما بسیار ساده به نظر می‌رسد. آن را با کدی که از Promise-های ساده استفاده می‌کرد و از زنجیره‌سازی و تابع‌های callback بهره می‌گرفت مقایسه کنید. این یک مثال بسیار ساده است، مزیت اصلی زمانی بروز می‌یابد که کد بسیار پیچیده‌تر باشد. برای نمونه با استفاده از Promise-ها به صورت زیر می‌توان یک منبع JSON را دریافت کرده و آن را تحلیل کرد:

کد زیر همان کارکرد فوق را با استفاده از await/async اجرا می‌کند:

سری کردن چند تابع Async

تابع‌های Async را می‌توان بسیار ساده به هم زنجیر کرد و ساختار آن نسبت به Promise-های ساده بسیار خواناتر است:

کد فوق عبارت زیر را نمایش می‌دهد:

I did something and I watched and I watched as well

دیباگ آسان‌تر

دیباگ کردن Promise-ها دشوار است زیرا دیباگر روی کد ناهمگام نمی‌ایستد. اما async/await کار دیباگ را بسیار آسان‌تر ساخته‌اند، زیرا از نظر کامپایلر آن‌ها کد همگام هستند.

Event Emitter در Node.js

با استفاده از Event Emitter در Node.js می‌توان رویدادهای سفارشی ایجاد کرد. اگر با جاوا اسکریپت در مرورگر کار کرده باشید، می‌دانید که بخش عمده تعامل با کاربر از طریق رویدادهایی مانند کلیک‌های ماوس، فشردن کلیدهای کیبورد، واکنش به حرکت ماوس و غیره مدیریت می‌شود. در سمت بک‌اند، Node.js کلاس EventEmitter را ارائه کرده است که برای مدیریت رویدادها استفاده می‌شود. این کلاس را می‌توان با استفاده از کد زیر مقداردهی کرد:

این شیء متدهای on و emit برخی متدهای دیگر را عرضه می‌کند.

  • emit – برای تحریک کردن یک رویداد استفاده می‌شود.
  • on – برای افزودن تابع callback استفاده می‌شود که قرار است هنگام تحریک شدن رویداد اجرا شود.

برای نمونه، یک رویداد start ایجاد می‌کنیم و از آنجا که می‌خواهیم مثال ساده‌ای باشد، واکنش ما به آن لاگ کردن پیامی در کنسول است:

زمانی که رویداد را اجرا کنیم:

تابع دستگیره رویداد تحریک می‌شود و لاگ کنسول ایجاد می‌شود. با استفاده از آرگومان‌های اضافی ()emit می‌توان آرگومان‌هایی به دستگیره رویداد ارسال کرد:

آرگومان‌های چندگانه

شیء EventEmitter چند متد دیگر نیز برای تعامل با رویدادها در اختیار ما قرار می‌دهد که از آن جمله‌اند:

  • ()once – یک شنونده یک‌بارمصرف اضافه می‌کند.
  • ()removeListener() / off – یک شنونده رویداد را از رویداد حذف می‌کند.
  • ()removeAllListeners – همه شنونده‌ها را از یک رویداد حذف می‌کند.

بدین ترتیب به پایان بخش هفتم از راهنمای جامع Node.js می‌رسیم. در بخش بعدی این راهنما در مورد پروتکل HTTP و طرز کار با آن در محیط Node صحبت خواهیم کرد. برای مطالعه بخش بعدی به لینک زیر مراجعه کنید:

ا

منبع: فرادرس

برنامه محاسبه e به توان عدد x — راهنمای کاربردی

در این مطلب، برنامه محاسبه e به توان عدد x ارائه شده است. محاسبه مقدار تابع نمایی ex با استفاده از «سری تیلور» (Taylor Series)، به صورت زیر، امکان‌پذیر است.

e^x = 1 + x/1! + x^2/2! + x^3/3! + ......

پرسشی که اکنون مطرح می‌شود این است که چگونه می‌توان به صورت کارا، مجموع سری بالا را محاسبه کرد. سری را می‌توان به صورت زیر نوشت:

e^x = 1 + (x/1) (1 + (x/2) (1 + (x/3) (........) ) )

مجموعی که نیاز به محاسبه آن برای n عبارت وجود دارد را می‌توان با استفاده از حلقه‌ای که در زیر آمده، محاسبه کرد.

for (i = n - 1, sum = 1; i > 0; --i )
sum = 1 + x * sum / i;

در ادامه، پیاده‌سازی راهکار بالا در زبان‌های برنامه‌نویسی ++C/C، «جاوا» (Java)، «پایتون 3» (Python 3)، «سی‌شارپ» (#C) و«پی‌اچ‌پی» (PHP) انجام شده است. برای آشنایی بیشتر با عدد e، مطالعه مطلب «توابع نمایی و عدد e — به زبان ساده» و همچنین، برای آشنایی بیشتر با سری تیلور، مطالعه مطلب «سری تیلور — از صفر تا صد» توصیه می‌شود.

برنامه محاسبه e به توان عدد x در ++C/C

برنامه محاسبه e به توان عدد x در جاوا

برنامه محاسبه e به توان عدد x در پایتون 3

برنامه محاسبه e به توان عدد x در سی شارپ

برنامه محاسبه e به توان عدد x در PHP

خروجی

همانطور که مشهود است، در قطعه کدهای بالا (همه کدهای ارائه شده برای زبان‌های گوناگون شامل پایتون، جاوا، ++C و سی‌شارپ)، مقدار x برابر با 1 وارد شده است. در نتیجه، خروجی قطعه کدهای بالا به ازای x=1، برابر با مقدار ارائه شده در زیر است.

e^x = 2.718282

ا

منبع: فرادرس