Fork me on GitHub

برنامه نویسی Event-Driven به سبک خاصی از برنامه نویسی می‌گویند که در آن جریان اجرای برنامه توسط Eventها تعیین می‌شود. در هنگام تعریف هر Event برنامه نویس موظف است برای آن Event یک Event-Handler یا Event-Callback نیز تعریف کند تا در هنگام اتفاق افتادن آن Event صدا زده شوند و وظیفه خود را انجام دهد. در مقاله‌ی فوق این مباحث را با مثال‌هایی از دنیای واقعی و همچنین کدهای برنامه نویسی توضیح می‌دهیم.

تعریف Event در دنیای واقعی

ما انسان‌ها هر روز با Eventها سروکار داریم. شاید بتوان اینطور گفت که برنامه نویسی Event-Driven بسیار به زندگی روزمره انسان‌ها شبیه است و برای همین فهم آن میتواند بسیار ساده باشد. برای مثال تصور کنید که در هنگام درست کردن یک نیمرو هستید. حالا بیایید تا Eventها و Event-Callbackهای درست کردن نیمرو را بررسی کنیم. برای مثال ما تعریف میکنیم که هر وقت روغن داخل ماهی‌تابه گرم شد (Event گرم شدن روغن اتفاق افتاد) ما تخم مرغ را روی آن میشکنیم (Event-Callback آن را صدا میزنیم). یا به عنوان مثال دیگر می‌توانیم بگوییم هر وقت تخم مرغ به اندازه کافی پخت (Event پختن تخم مرغ اتفاق افتاد) ما زیر گاز را خاموش می‌کنیم (Event-Callback آن را صدا می‌زنیم). و خب از همین دست میتوانیم هزاران مثال دیگر که در زندگی روزمره ما اتفاق می‌افتد را بیان کنیم.

تعریف Event در دنیای برنامه نویسی

در دنیای برنامه نویسی وقتی شما روی یک لینک کلیک می‌کنید یک Event اتفاق می‌افتد. حتی وقتی نتیجه یک Query که به Database فرستاده‌اید به دست می‌آید یک Event اتفاق می‌افتد.
در سبک برنامه نویسی غیر Event-Driven که ما از اتفاقات بهره‌ای نمی‌بردیم این Query به صورت زیر نوشته می‌شد:

result = database_query('SELECT * FROM posts WHERE id = 1');
do_something_with
(result);

در این روش ما باید منتظر بمانیم تا نتیجه Query از Database بازگردد و سپس عملیات مورد نظر خود را با نتیجه حاصل شده انجام دهیم. یعنی تا وقتی خط اول جواب ندهد جریان اجرای برنامه نمی‌تواند به خط بعدی برود. با تصور اینکه Query ما نیاز به زمان زیادی برای به دست آوردن نتیجه داشته باشد، بی‌شک جریان برنامه ما باید منتظر بماند تا نتیجه Query حاصل شود. در این مواقع در ادبیات برنامه نویسی می‌گوییم برنامه ما Block می‌شود.
حالا بیاییم با استفاده از سبک Event-Driven همین عملیات را تکرار کنیم:

query_finished = function(result) {
    do_something_with
(result);
}
database_query
('SELECT * FROM posts WHERE id = 1', query_finished(result));
do_something_else
();

در اینجا شما ابتدا در تابع query_finished تعریف می‌کنید که وقتی Query تمام شد ما با تنیجه‌ی آن باید چه کار کنیم (مثل وقتی که در ذهنتان تعریف میکنید به محض اینکه روغن در ماهی‌تابه گرم شد باید تخم مرغ را بشکنیم). سپس تابع query_finished را به عنوان پارامتر دوم به تابع database_query می‌فرسیتم به این معنی که هر وقت تابع database_query نتیجه Query را بدست آورد آن را به عنوان پارامتر به تابع query_finished بفرستد. دقت کنید که در اینجا تابع query_finished به عنوان Event-Callback تابع database_query است. نکته‌ی جالب اینجاست که حتی اگر تابع database_query برای گرفتن نتیجه از Database نیاز به ۱۰ ثانیه زمان داشته باشد، باز هم جریان برنامه شما صرف نظر از این میزان اتلاف زمان به سرعت و بدون معطلی به خط بعدی خود می‌رود تا تابع do_something_else را انجام دهد. در اصطلاح برنامه نویسی برنامه شما Block نمی‌شود. ضمنا باید دقت کنید که در سبک برنامه نویسی Event-Driven شما نبایستی برای توابع خود Return Value تعریف کنید زیرا این کار باعث می‌شود تا وقتی که تابع شما Retun Value خود را برنگرداند، برنامه شما در حالت Block باقی بماند.

برنامه نویسی Blocking I/O و Non-Blocking I/O

یک خبر خوب، شما در این مقاله با دو مفهوم جدید دیگر هم آشنا شدید. مفهوم Blocking I/O Programming و Non-Blocking I/O Programming. در قسمت اول که شما منتظر Return Value تابع database_query بودید برنامه شما به سبک Blocking I/O نوشته شده بود. یعنی جریان برنامه تا زمان دریافت نتیجه تابع database_query متوقف یا Block شده بود. اما در قسمت دوم با استفاده از سبک Event-Driven به نوعی شما از Block شدن جریان برنامه خود نیز جلوگیری کردید و Non-Blocking I/O برنامه نوشتید.

با چه زبان‌هایی میتوان Event-Driven برنامه نوشت

یکی از معروف‌ترین زبان های برنامه نویسی در این خصوص زبان JavaScript است. دلیل این که چرا JavaScript از سبک Event-Driven پشتیبانی می‌کند بسیار ساده و قابل حدس زدن است. همانطور که میدانید JavaScript در ابتدا برای مرورگرهای وب تولید شد. حالا بیایید و Eventهایی که یک مرورگر وب با آن سروکار دارد را بشمریم؛ کلیک راست کردن، کلیک چپ کردن، وارد شدن نشانگر ماوس به یک محدوده، خارج شدن از آن محدوده، فشار دادن دکمه‌های کیبورد و بسیاری Eventهای دیگر که وب سایت ها به آنها در هر لحظه پاسخ می‌دهند. پس نتیجه میگیریم که JavaSctipt باید Event-Driven باشد.
به عنوان مثال دیگر می‌توان NodeJS را نام برد که با ابتکار Ryan Dahl (خالق NodeJS) و با استفاده از Google V8 Engine (موتور تفسیر کدهای JavaScript که توسط شرکت Google تولید شده) به ما امکان میدهد در سمت سرور هم با استفاده از JavaScript برنامه بنویسیم.
از دیگر زبان هایی که Event-Driven Programming را پشتیبانی میکنند میتوان Lua، Simula، Smalltalk، Tcl، ActionScript و بسیاری دیگر را نام برد.