Trong thế giới lập trình hiện đại, việc xử lý các tác vụ không đồng bộ ngày càng trở nên quan trọng. Ngôn ngữ lập trình Dart và Flutter framework của Google cung cấp hai công cụ mạnh mẽ để làm việc với lập trình không đồng bộ: Future và Streams. Trong bài viết này, chúng ta sẽ tìm hiểu về cả hai, cũng như cách chúng được sử dụng trong Flutter.
Future trong Dart
Future là một cách để thực hiện công việc có thể mất một thời gian dài để hoàn thành, như đọc dữ liệu từ ổ đĩa hoặc thực hiện yêu cầu HTTP, mà không cần chặn luồng thực thi chính.
Dưới đây là ví dụ về cách sử dụng Future trong Dart:
Trong ví dụ trên, fetchUserOrder trả về một Future<String>. Khi Future hoàn thành, giá trị trả về được xử lý trong hàm callback của phương thức then.
Streams trong Dart
Streams giống như Future, nhưng thay vì chỉ trả về một giá trị, chúng có thể phát nhiều sự kiện giá trị theo thời gian. Streams là cách tốt để làm việc với dữ liệu không đồng bộ nếu bạn cần xử lý nhiều sự kiện hoặc giá trị.
Dưới đây là một ví dụ về cách sử dụng Streams:
Trong ví dụ này, countStream tạo ra một Stream phát các số từ 1 đến to mỗi giây. Chúng ta sau đó nghe Stream này và in ra mỗi giá trị khi nó xuất hiện.
Sử dụng Future và Streams trong Flutter
Trong Flutter, cả Future và Streams đều đóng một vai trò quan trọng trong việc xây dựng ứng dụng phản ứng. Ví dụ, bạn có thể dùng Future để tải dữ liệu từ API và cập nhật giao diện khi dữ liệu sẵn sàng.
Trong ví dụ về Future, chúng ta đang tạo một Future trả về chuỗi "Cà phê sữa đá" sau 3 giây. FutureBuilder sau đó lắng nghe Future này và cập nhật giao diện khi dữ liệu sẵn sàng.
Một khía cạnh khác của lập trình phản ứng trong Flutter là sử dụng StreamBuilder để lắng nghe các sự kiện từ một Stream. Dưới đây là một ví dụ về cách sử dụng StreamBuilder:
Đối với ví dụ về Stream, chúng ta tạo ra một Stream phát số từ 1 đến 5 mỗi giây. StreamBuilder lắng nghe Stream này và cập nhật giao diện với mỗi số mới.
Một vài lưu ý cho các lập trình viên khi sử dụng Streams và Future trong Flutter
Có một số điểm quan trọng mà các lập trình viên Flutter cần nhớ khi sử dụng Future và Streams:
1. Xử lý các trạng thái của Future và Stream
Khi sử dụng FutureBuilder hoặc StreamBuilder, bạn cần xử lý tất cả các trạng thái có thể của Future hoặc Stream. Điều này bao gồm việc xử lý trạng thái chờ, trạng thái hoàn thành và trạng thái lỗi.
2. Đảm bảo Future và Stream không bị rò rỉ
Future và Stream nếu không được xử lý đúng cách có thể dẫn đến các vấn đề về hiệu suất và bộ nhớ. Đảm bảo rằng bạn luôn hủy bỏ các subscription Stream khi không cần sử dụng nữa. Ví dụ, bạn có thể thực hiện việc này trong phương thức dispose của StatefulWidget.
Dưới đây là một ví dụ mô phỏng về việc StreamBuilder. StreamBuilder tự động hủy bỏ subscription khi widget bị loại bỏ, do đó không cần lo lắng về việc hủy bỏ thủ công:
Trong ví dụ này, StreamBuilder lắng nghe một Stream phát số từ 0 mỗi giây và cập nhật giao diện với mỗi số mới.
3. Cân nhắc sử dụng các thư viện quản lý trạng thái
Có nhiều thư viện quản lý trạng thái trong Flutter (như Provider, Riverpod, Bloc, vv.) có thể giúp bạn quản lý và xử lý Future và Streams một cách hiệu quả hơn.
Ví dụ về cách sử dụng Provider để quản lý một giá trị đơn giản:
Ở đây, chúng ta đang sử dụng ChangeNotifierProvider để cung cấp ValueNotifier<int>, một loại ChangeNotifier đơn giản, cho toàn bộ ứng dụng. Khi nhấn vào FloatingActionButton, giá trị trong ValueNotifier<int> sẽ tăng lên, và widget Text sẽ tự động cập nhật để hiển thị giá trị mới này.
4. Hiểu rõ về việc chạy song song và tuần tự
Future trong Dart mặc định sẽ chạy tuần tự trên một luồng. Tuy nhiên, với Future.wait, bạn có thể chạy nhiều Future song song. Với Streams, bạn có thể sử dụng các phương thức như Stream.map, Stream.where, Stream.expand, vv. để xử lý và biến đổi dữ liệu một cách linh hoạt.
Dưới đây là một ví dụ về việc chạy tuần tự và song song với Future trong Dart:
Chạy tuần tự:
Trong ví dụ này, 'Future 2' sẽ chờ 'Future 1' hoàn thành trước khi bắt đầu, vì vậy chúng được thực hiện tuần tự.
Chạy song song:
Trong ví dụ này, 'Future 1' và 'Future 2' được bắt đầu cùng một lúc và chạy song song. Future.wait chờ cho tất cả Future hoàn thành trước khi tiếp tục.
Kết luận
Future và Streams là hai công cụ mạnh mẽ trong ngôn ngữ lập trình Dart cho việc xử lý các tác vụ không đồng bộ. Flutter tận dụng chúng thông qua FutureBuilder và StreamBuilder để tạo ra ứng dụng phản ứng mạnh mẽ và linh hoạt. Hi vọng sau bài viết này, bạn đã hiểu rõ hơn về cách sử dụng Future và Streams trong Dart và Flutter.
Nếu bạn đang muốn phát triển kỹ năng về lập trình với Flutter và tham gia vào các dự án thực chiến thì có thể gửi CV tới ITBee Solutions.
Chúc bạn may mắn và thành công!