توی فلاتر یه زمان هایی هست که میخوایم دیتایی رو از سرور دریافت کنیم یا دیتایی رو توی دیتابیس بنویسیم یا حتی دیتایی رو از فایلی بخونیم اگر بصورت همزمان یا Synchronous انجام بدیم باعث میشه که برنامه ما فریز بشه و تا زمانی که این عملیات انجام نشده کاربر ما هر حرکتی روی اپلیکیشن بزنه انگار نه انگار برنامه کار میکنه و اگر این عملیات طول بکشه کاربر حتی فکر میکنه که برنامه ما هنگ کرده و فوش و الی آخر
برای اینکه بتونیم از دعوا و مرافعه دوری کنیم میایم از برنامه نویسی ناهمزمان یا Asynchronous استفاده میکنیم، حالا چطوری؟
برای استفاده از برنامه نویسی ناهمزمان در دارت ما از این کلمات کلیدی استفاده میکنیم:
نتیجه های محاسبات ناهمزمان معمولا بصورت Future است یعنی خروجی Future به ما می دهد و اگر نتیجه های ما چند بخشی باشد مثل صفحه بندی (Pagination) که باید درخواست صفحه بعد داد رو با Stream پیاده سازی میکنیم
یک Future در واقع نشان دهنده عملیات ناهمزمانه که دو حالت براش هست
در این وضعیت زمانی که شما یک فانکنش ناهمزمان (Future) را فراخوانی می کنید، همون موقع یک Future تکمیل نشده به شما بر میگردونه که درحال پروسه انجام، حالا ممکنه این پروسه تکمیل بشه یا ارور برگشت داده بشه
2. تکمیل شده
در این وضعیت عملیات موفقیت آمیز بوده و Future ما تکمیل شده به همراه مقدار و یا ممکنه تکمیل شده همراه با ارور
این فیوچر ها میتونن مقدار بگیرن مثل String یا هر تایپی که تعریف کرده باشیم که به شکل <Future<T که T همون تایپ مقدار ما هستن که برای رشته میشه <Future<String
برای مثال
Future<void> fetchUserOrder() {
// فکر کنید این تابع از دیتابیس دیتایی رو میگیره و به مدت 2 ثانیه طول میکشه.
return Future.delayed(const Duration(seconds: 2), () => print('Got it From Database'));
}
void main() {
fetchUserOrder();
print('Fetching user order from database...');
}
ما از زمانی که فانکشن ناهمزمان خودمون رو یعنی fetchUserOrder رو فراخوانی میکنیم بعد از دو ثانیه تاخیر که بصورت فیک با Future.delayed بهش دادیم مقدار Got it From Database رو برامون پرینت میکنه و براش فرقی نداره که چه کد هایی بعدش هست.
خب پس خروجی نهایی کد میشه
Fetching user order from database...
Got it From Database // مشاهده بعد از دو ثانیه
کلمات کلیدی async و await برای ما این امکان رو فراهم میکنه که توی فانکشن های ناهمزمان استفاده کنیم و از مقدار نهایی آنها بهره مند شیم که دوتا نکته داره
برای اینکار در مرحله اول فانکشن main رو تبدیل به فیوچر میکنیم و کلمه کلیدی async رو قبل از بدنه اضافه
و در کد زیر فانکشن countSecond میاد بصورت ناهمزمان ثانیه هارو میشماره که تا 6 ثانیه هست
فانکشن getOrderMessage داریم که با چهار ثانیه تاخیر مقدار "Order message" بر میگردونه
یه نکته رو بگم که کلید واژه await به معنی صبر کردن هست و این کلمه کلیدی میاد بعد از صبر مقدار رو برمیگردونه
خب میایم میگیم که برای فانکشن getOrderMessage صبر کن تا مقدار واقعیش رو بربگردونه و بعد مقدار رو پرینت کن
حالا اگر کد رو اجرا کنیم ...
Future<void> main() async {
countSeconds(6);
final result = await getOrderMessage();
print(result);
}
Future<String> getOrderMessage() async {
await Future.delayed(Duration(seconds: 4));
return "Order message";
}
void countSeconds(int s) {
for (var i = 1; i <= s; i++) {
Future.delayed(Duration(seconds: i), () => print(i));
}
}
نتیجه رو به شکل زیر میبینیم که بعد از ثانیه 4 مقدار Order message چاپ میشه
result:
1
2
3
4
Order message
5
6
امیدوارم تونسته باشم مفهوم فیوچر رو جا انداخته باشم
منبع من برای این نوشته وبسایت pub.dev هست