Async in Dart
หนึ่ง thread กับ event loop
หัวข้อที่มีชื่อว่า “หนึ่ง thread กับ event loop”Dart รัน code ของคุณบน single thread พร้อม event loop — model เดียวกับ JavaScript ใน code ปกติไม่มี threading แบบ shared-memory แต่ async operation (network, file, timer) จะรันที่อื่น แล้ว schedule callback บน event loop เมื่อเสร็จ
นี่คือเหตุผลที่ “async” ใน Flutter ไม่ได้แปลว่า “อีก thread” แต่แปลว่า “อย่า block thread เดียวที่เรามี” loop แบบ synchronous ที่ช้าจะ freeze UI แต่การ await network call ไม่ freeze เพราะ thread ว่างพอจะ render frame ระหว่างรอ
flowchart LR ui["UI thread (event loop)"] -->|await fetch| free["thread ว่าง พอจะ render frame"] free -->|response มาถึง| cb["callback ถูก schedule บน loop"] cb --> resume["code ของคุณทำงานต่อ"]
Future และ async/await
หัวข้อที่มีชื่อว่า “Future และ async/await”Future<T> คือค่าที่จะมีทีหลัง — ผลของ async operation async/await ให้คุณเขียนโค้ด async ให้อ่านเหมือนโค้ด sequential
Future<User> fetchUser(int id) async { final response = await http.get(Uri.parse('/users/$id')); // รอ แต่ไม่ block return User.fromJson(response.body);}
// เรียกใช้:Future<void> load() async { try { final user = await fetchUser(42); print(user.name); } catch (e) { print('failed: $e'); // future ที่ await จะ throw error ที่ try/catch ได้ }}function ที่เป็น async คืน Future เสมอ await แกะค่าข้างในออกมา และที่สำคัญ — error จาก future ที่ await จะโผล่มาเป็น exception ปกติที่ try/catch ได้ ใน Flutter คุณแทบไม่ await ใน build แต่ส่ง Future ให้ FutureBuilder แทน (โมดูลถัดไป)
Stream: หลายค่าตามเวลา
หัวข้อที่มีชื่อว่า “Stream: หลายค่าตามเวลา”Stream<T> เหมือน Future ที่ส่งค่า หลายค่า — ลำดับของ event ตามเวลา: ข้อความ web-socket, ค่า sensor, input ของ user, การเปลี่ยนแปลงของ database
Stream<int> ticker() async* { // async* ทำให้เป็น Stream; yield emit ค่า for (var i = 1; i <= 3; i++) { await Future.delayed(const Duration(seconds: 1)); yield i; // emit 1, แล้ว 2, แล้ว 3 }}
// consume ด้วย await-for หรือ .listen:await for (final tick in ticker()) { print(tick); // 1, 2, 3 — หนึ่งค่าต่อวินาที}การแยก Future/Stream map เข้ากับ Flutter ได้พอดี: async แบบ one-shot → FutureBuilder; stream ของ update → StreamBuilder เข้าใจความต่างนี้ให้ถูกก็เท่ากับเข้าใจ “async ใน Flutter” ไปเกือบหมดแล้ว
Isolate: parallelism จริง เมื่อจำเป็น
หัวข้อที่มีชื่อว่า “Isolate: parallelism จริง เมื่อจำเป็น”ข้อยกเว้นเดียวของ “single thread” คือ isolate — worker แยกที่มี memory ของตัวเอง สื่อสารด้วยการส่ง message (ไม่มี shared state) คุณหยิบมาใช้เฉพาะงานที่หนัก CPU จริง ๆ (parse JSON ก้อนใหญ่, image processing) ที่ไม่งั้นจะทำให้ UI jank Flutter ห่อ case ทั่วไปไว้ใน compute() ซึ่งอยู่ในโมดูล performance