نکات Future

توی قسمت قبلی در مورد Event Loop صحبت کردیم و گفتیم که توی دارت دو تا Queue داریم:

  • Microtask Queue
  • Event Queue

Microtask ها توسط فانکشن ScheduleMicrotask اد میشدن (داخل خود کد) و event ها هم از بیرون میومدن.

حالا توی این قسمت constructor های کلاس Future رو با هم بررسی میکنیم.

factory Future(FutureOr<T> computation())

همون طور که توی قسمت قبلی هم دیدیم این کانستراکتور یه دونه تایمر با مدت زمان صفر رجیستر میکنه. پس کابلکی که بهش پاس میدیم یعنی computation باید بلافاصله اجرا بشه. ولی چون که تایمر ها یه event به Event Loop اضافه میکنن, پس بعد از فراخونی این کانستراکتور, کد داخل کالبک بلافاصله اجرا نمیشه و باید منتظر بمونیم تا متد main خاتمه پیدا کنه و بعدش Microtask queue خالی بشه و بعدش که event loop اومد سر وقت even queue نوبت به اجرای کالبک مورد نظر برسه.

factory Future.microtask(FutureOr<T> computation())

این یکی کانستراکتور همون طور که از اسمش مشخصه یه دونه مایکروتسک رو برنامه ریزی یا schedule میکنه. پس قبل از همه ی event ها بهش رسیدگی میشه و اجرا میشه.

factory Future.sync(FutureOr<T> computation())

همون طور که از اسمش و سورس کدش مشخصه, این کانستراکتور دیگه async نیست و هیچ event یا microtask ای رو رجیستر نمیکنه و بلافاصله اجرا میشه.

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

void main(List<String> arguments) {
  
  print('main #1 ');
  scheduleMicrotask(() => print('microtask '));

  Future.sync(() => print('Future sync'));

  
  print('main #2 ');
}

میبینی که دقیقن مثل بقیه کدها باهاش برخورد شده!!!

factory Future.delayed(Duration duration, [FutureOr<T> computation()?])

این یکی هم که کاملن مشخصه و یه تایمر رجیستر میکنه و در نهایت یه event که به event queue اضافه میشه.

factory Future.value([FutureOr<T>? value])

به کد زیر دقت کن:

void main(List<String> arguments) {
  
  print('main #1 ');
  scheduleMicrotask(() => print('microtask '));

  Future.value("future value")
    .then((value) => print(value));

  
  print('main #2 ');
}

این کانستراکتور یه microtask اضافه میکنه به microtask queue.

factory Future.error(Object error, [StackTrace? stackTrace])

این هم دقیقن شبیه به قبلی هست, با این تفاوت که به جای اینکه با یه ولیو complete بشه با یه ارور complete میشه.

نکته

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

void main(List<String> arguments) {
  
  print('main #1 ');
  scheduleMicrotask(() => print('microtask '));

  Future.sync(() => print("Future sync"))
    .then((value) => print("on then"));

  
  print('main #2 ');
}

حتمن میگی اینطوریه:

main #1

Future sync

on then

main #2

microtask

درسته؟

ولی اشتباه گفتی. جواب درست به شکل زیر هست:

خب اول main #1 چاپ میشه و بعدش میرسه به Future.sync و چون که این کانستراکتور هیچ event یا micro ای رو رجیستر نمیکنه پس Future sync چاپ میشه.

ولی اصل داستان از اینجا شروع میشه. بعد از چاپ شدن Future sync میرسه به متد then و چون که متد then داره روی یه فیوچری که از قبل complete شده اجرا میشه, پس بلافاصله محتویات توش یعنی کالبکش اجرا نمیشه, بلکه یه مایکروتسک رو رجیستر میکنه!!!

بعد از اون main #2 چاپ میشه و بعد نوبت میرسه به micro ها که دوتا توی صف هستن. یکی مایکروی اولی که microtask رو چاپ میکنه و یکی هم مایکرویی که توسط then رجیستر شده بود و on then رو چاپ میکنه.

پ.ن: این نکته با مثال Future.Sync بیان شد ولی اصل نکته رو بگیر. هر وقت به یه کد به یه فیوچری برسه که از قبل complete شده, کالبک داخل متد then بلفاصله اجرا نمیشه, بلکه یه micro رجیستر میشه.

دیدگاهتان را بنویسید

error: Alert: Content is protected !!