🧠 أولًا: ما المقصود بـ “تزامن”؟
“تزامن” هنا يعني: هل ينتظر البرنامج انتهاء العملية الحالية قبل تنفيذ العملية التالية؟
✅ البرمجة التزامنية (Synchronous Programming)
🔹 المفهوم:
هي الطريقة التقليدية في تنفيذ الأوامر، حيث يتم تنفيذ كل أمر واحدًا تلو الآخر، ولا يتم الانتقال للسطر التالي إلا بعد الانتهاء من السطر الحالي.
🔁 مثال واقعي:
أنت تقف في طابور في البنك. لا يتم خدمة الشخص التالي إلا بعد أن ينتهي الشخص الحالي.
📄 مثال برمجي (Dart):
print('1');
print('2');
print('3');Dart🔸 الناتج:
1
2
3Dartكل أمر ينتظر السابق أن ينتهي.
🔄 البرمجة غير التزامنية (Asynchronous Programming)
🔹 المفهوم:
يتم تنفيذ الأوامر بدون الانتظار، خاصة تلك التي تحتاج وقتًا طويلًا (مثل القراءة من الإنترنت أو القرص)، ويتم متابعة تنفيذ الكود دون توقف، ثم تُعاد النتيجة لاحقًا عندما تصبح جاهزة.
🔁 مثال واقعي:
أنت تطلب وجبة من مطعم. تطلب الوجبة وتذهب تجلس، ويأتيك النادل بها لاحقًا. لا تنتظر واقفًا.
📄 مثال برمجي (Dart) باستخدام Future:
void main() {
print('1');
Future.delayed(Duration(seconds: 2), () {
print('2');
});
print('3');
}Dart🔸 الناتج:
1
3
2Dartلأن السطر الذي فيه Future.delayed ينتظر 2 ثانية، فيُكمل البرنامج تنفيذ السطر الذي بعده ثم يعود لطباعة “2” بعد التأخير.
🔧 لماذا نستخدم البرمجة غير التزامنية؟
📌 الأهمية:
- ✅ تحسين الأداء: لا يتم تجميد التطبيق أثناء العمليات الثقيلة.
- ✅ السلاسة في واجهة المستخدم: في تطبيقات مثل Flutter أو الويب، لا يتجمد التطبيق أثناء تحميل البيانات.
- ✅ إدارة المهام المؤقتة: مثل الاتصال بالسيرفر، قراءة الملفات، استعلامات قواعد البيانات، إلخ.
⚙️ أدوات البرمجة غير التزامنية في Dart:
Future: نتيجة ستصل في المستقبل.async/await: تسهّل كتابة الكود غير التزامني بطريقة تشبه التزامني.Stream: للتعامل مع البيانات المتدفقة (مثل استقبال رسائل متعددة من API).
🎯 خلاصة سريعة:
| المقارنة | التزامنية (Synchronous) | غير التزامنية (Asynchronous) |
|---|---|---|
| التنفيذ | أمر بعد أمر | قد تُكمل الأوامر في وقت لاحق |
| الأداء | أبطأ في العمليات الثقيلة | أسرع وأكثر تفاعلية |
| الاستخدام المناسب | أوامر بسيطة وسريعة | قراءة الملفات، الشبكة، انتظار المستخدم |
🚀 ما هو Future؟
Future معناها عملية ستحدث في المستقبل وتستغرق بعض الوقت لتنتهي، مثل:
- الانتظار لتحميل بيانات من الإنترنت.
- قراءة ملف من الجهاز.
- الانتظار لمدة معينة.
🔹 Dart لا “توقف” البرنامج، بل تتابع التنفيذ وتُكمل العملية لاحقًا.
✅ شكل Future في Dart
Future<int> getNumber() {
return Future.delayed(Duration(seconds: 2), () => 10);
}Dart- الدالة ترجع
Future<int>→ أي “قيمة صحيحة ستأتي لاحقًا“. - تستخدم
Future.delayedلتأخير 2 ثانية.
✳️ الطريقة الأولى: باستخدام then()
void main() {
print("Start");
getNumber().then((value) {
print("The number is $value");
});
print("End");
}
Future<int> getNumber() {
return Future.delayed(Duration(seconds: 2), () => 10);
}Dart🔹 الناتج:
Start
End
The number is 10Dart✅ الكود يُكمل دون انتظار، ويطبع القيمة لاحقًا عندما تصل.
✳️ شرح ما يحدث:
1. print("Start");
يطبع مباشرة:
StartDart2. getNumber().then((value) { ... });
هنا:
getNumber()تُعيد كائنFutureيُكمل بعد تأخير مدته ثانيتين (Future.delayed).- عند اكتمال الـ Future، يتم استدعاء الكود داخل
then()وتنفيذ الطباعة: csharpCopyEditThe number is 10
⚠️ لكنه لا ينتظر تنفيذ getNumber()، بل يذهب للسطر التالي مباشرة.
3. print("End");
يطبع مباشرة بعد Start لأن getNumber() لم تُنَفذ بعد (هي مؤجلة):
EndDart🔁 النتيجة الفعلية عند تشغيل البرنامج:
Start
End
The number is 10Dart🎯 ما فائدة then()؟
then() تستخدم للتعامل مع نتيجة الـ Future عندما تجهز.
هي وسيلة لربط كود معين يتم تشغيله بعد الانتهاء من العملية المؤجلة.
مثال واقعي:
Future<String> fetchUsername() {
return Future.delayed(Duration(seconds: 2), () => "Yasin");
}
void main() {
fetchUsername().then((username) {
print("Welcome $username");
});
}Dart❓ لماذا لا ينتظر Future؟
لأن Future يعمل بشكل لا تزامني (Asynchronous):
- لا يوقف تنفيذ البرنامج.
- يتيح تنفيذ التعليمات الأخرى ريثما يكتمل العمل المؤجل.
- هذا يُفيد في عدم تجميد التطبيق، خصوصًا في تطبيقات الواجهات الرسومية أو الشبكات.
🔄 بديل then() — استخدام async و await:
Future<int> getNumber() {
return Future.delayed(Duration(seconds: 2), () => 10);
}
void main() async {
print("Start");
int number = await getNumber(); // ينتظر حتى تجهز القيمة
print("The number is $number");
print("End");
}Dart💡 الناتج:
Start
The number is 10
EndDartهنا، await أوقفت التنفيذ مؤقتًا حتى تجهز القيمة.
✅ ملخص:
| العنصر | الوظيفة |
|---|---|
Future | كائن يمثل عملية ستكتمل لاحقًا (مثلاً تحميل ملف أو بيانات من الإنترنت). |
then() | تُستخدم للتعامل مع القيمة بعد اكتمال الـ Future. |
await | تجعل البرنامج ينتظر القيمة بدلًا من المتابعة مباشرة. |
async | توضع مع main أو أي دالة تحتوي await. |
✳️ الطريقة الثانية: باستخدام async/await
void main() async {
print("Start");
int number = await getNumber();
print("The number is $number");
print("End");
}
Future<int> getNumber() {
return Future.delayed(Duration(seconds: 2), () => 10);
}Dart🔹 الناتج:
Start
The number is 10
EndDart✅ عند استخدام
await، ينتظر البرنامج النتيجة قبل أن يُكمل.
📌 متى نستخدم Future؟
عند التعامل مع أي شيء يأخذ وقتًا مثل:
- جلب بيانات من الإنترنت.
- الانتظار لرد من المستخدم.
- الاتصال بقاعدة البيانات.
- قراءة أو كتابة ملفات.
✅ مثال عملي: دالة ترجع رسالة بعد وقت
Future<String> fetchMessage() {
return Future.delayed(Duration(seconds: 3), () => "تم تحميل الرسالة!");
}
void main() async {
print("جاري التحميل...");
String msg = await fetchMessage();
print(msg);
}Dart✅ مثال: استخدام Future مع شرط
Future<String> checkLogin(String user, String pass) {
return Future.delayed(Duration(seconds: 2), () {
if (user == "admin" && pass == "1234") {
return "تم تسجيل الدخول بنجاح";
} else {
return "فشل تسجيل الدخول";
}
});
}
void main() async {
print("جارٍ تسجيل الدخول...");
String result = await checkLogin("admin", "1234");
print(result);
}Dart⚠️ التعامل مع الأخطاء في Future
باستخدام catchError:
Future<int> getError() {
return Future.delayed(Duration(seconds: 1), () => throw "حدث خطأ");
}
void main() {
getError().then((value) {
print("النتيجة: $value");
}).catchError((error) {
print("الخطأ: $error");
});
}Dartباستخدام try/catch مع async/await:
void main() async {
try {
int value = await getError();
print("النتيجة: $value");
} catch (e) {
print("حدث خطأ: $e");
}
}Dart🔄 الانتظار على أكثر من Future:
✅ Future.wait:
void main() async {
List<Future<String>> tasks = [
Future.delayed(Duration(seconds: 2), () => "مهمة 1"),
Future.delayed(Duration(seconds: 1), () => "مهمة 2"),
];
List<String> results = await Future.wait(tasks);
print(results); // [مهمة 1, مهمة 2]
}Dart✅ تلخيص مهم
| الكلمة | معناها |
|---|---|
Future<T> | قيمة ستعود من نوع T في المستقبل |
await | انتظر النتيجة قبل المتابعة |
async | اجعل الدالة تستطيع استخدام await |
then() | أسلوب لاستقبال النتيجة لاحقًا |
catchError / try-catch | للتعامل مع الأخطاء |