Berdebar. Asynchrony (async) <> paralelisme (isolate). Sama sekali

pengantar



Baru-baru ini, saya terkejut saat mengetahui bahwa kolega saya tidak memiliki kejelasan lengkap tentang asynchrony di Flutter. Untuk beberapa alasan, mereka memiliki gagasan bahwa jika fungsi asynchronous ditulis dengan benar, maka itu tidak memblokir antarmuka. Setelah menelusuri beberapa artikel, saya tidak menemukan penjelasan yang sederhana, lengkap, dan jelas tentang seluruh dapur ini (semuanya sesuai dengan prinsip - "pilih 2 dari 3")). Dalam satu artikel saya bahkan membaca bahwa Dart memiliki beberapa asynchrony yang luar biasa, yang memungkinkan Anda untuk menunda eksekusi kode hingga utasnya lebih bebas (yang menurut saya sedikit menyesatkan) (Catatan: di komentar nikita_dolmenunjukkan apa yang mungkin berarti - scheduleTask ).



Untuk siapa artikel tersebut



Artikel ini ditujukan bagi mereka yang baru mulai mengenal Flutter, jadi saya akan mencoba menunjukkan dengan contoh sederhana dalam catatan kecil ini bahwa asynchrony hanyalah kemampuan untuk mengeksekusi kode tidak secara berurutan. Namun, jika Anda memiliki fungsi "berat" (meskipun tiga kali asinkron), itu masih akan memblokir antarmuka untuk Anda. Tentu saja, dalam produk nyata, Anda tidak mungkin menemukan manifestasi yang begitu jelas (saat ini, prosesornya cukup kuat), tetapi masih perlu dipahami cara kerjanya.



Pergilah



Jadi, mari kita ambil contoh dari dokumentasi untuk pustaka flutter_bloc untuk eksperimen . Mari kita sedikit memodifikasi fungsi "_mapTimerStartedToState" dari kelas timer_bloc - beri komentar pada counter update sehingga tidak mengganggu:



Stream<TimerState> _mapTimerStartedToState(TimerStarted start) async* {
  yield TimerRunInProgress(start.duration);
  _tickerSubscription?.cancel();
  // _tickerSubscription = _ticker
  //     .tick(ticks: start.duration)
  //     .listen((duration) => add(TimerTicked(duration: duration)));
}

      
      







Mari tambahkan fungsi statis baru (kita membuatnya seperti ini sebelumnya - isolate hanya berfungsi dengannya) fungsi:



static Future<void> _heavyComput (SendPort sendPort) async {
  await Future.delayed(Duration(seconds: 5));

  print('=======================');
  print('!!!function finished!!!');
  print('=======================');
  return null;
}

      
      







Di sini, sebagai emulasi perhitungan berat, kami menunggu akhir penundaan 5 detik.

Kami memodifikasi fungsi mapEventToState - tambahkan panggilan asinkron ke _heavyComput di akhir:



@override
Stream<TimerState> mapEventToState(
  TimerEvent event,
) async* {

. . .
  
  _heavyComput(null);
}

      
      







Untuk tes pertama, semuanya sudah siap - tugas kita adalah mengamati gelombang ajaib.

Kami meluncurkan dan melihat - gelombang khawatir, antarmuka tidak diblokir, pesan tentang akhir fungsi ditampilkan setelah 5 detik.







Ini asynchrony yang luar biasa - kepanikan itu salah. Hmm ... Bagaimana jika Future.delayed (Duration (detik: 5)) diganti dengan loop?



static Future<void> _heavyComput(SendPort sendPort) async {
  int pause = 1200000000;
  for (int i = 0; i < pause; i++) {}
  print('=======================');
  print('!!!function finished!!!');
  print('=======================');
  return null;
}

      
      





Kami meluncurkannya dan hanya itu - "tiba" - ombak tidak lagi mengkhawatirkan.







Saya tidak berpikir banyak penjelasan yang diperlukan di sini: bahkan fungsi berat asinkron memblokir semuanya. Secara default, semua kode dijalankan dalam satu thread. Hanya saja pada kasus pertama, tidak diperlukan perhitungan, tetapi Anda hanya harus menunggu, dan pada kasus kedua, diperlukan perhitungan.



Nah, agar artikel tidak sepenuhnya mikroskopis, sebut saja fungsi ini menggunakan isolate. Mari kita ubah mapEventToState:



@override
Stream<TimerState> mapEventToState(
  TimerEvent event,
) async* {
. . .
  var _receivePort = ReceivePort();
  var _isolate = Isolate.spawn(_heavyComput, _receivePort.sendPort);
}

      
      







Kami memulainya dan melihat bahwa antarmuka tidak diblokir, kami menerima pesan tentang penyelesaian fungsi dengan penundaan yang nyata.







Itu saja (cara kerja async dan menunggu - ada banyak artikel, saya pikir Anda tidak boleh berhenti di situ).



Contoh dapat diunduh dari tautan - flutter_timer_async_and_parallels



All Articles