Dart Async liên quan đến lập trình không đồng bộ. Nó thực hiện hoạt động không đồng bộ trong một luồng. Nó đảm bảo rằng các chức năng quan trọng sẽ được thực thi cho đến khi hoàn thành. Hoạt động không đồng bộ được thực thi, riêng luồng ứng dụng chính. Trong Dart, một thao tác không thể làm gián đoạn thao tác kia; nó có nghĩa là một hoạt động có thể thực hiện tại một thời điểm mà không phần nào khác của chương trình có thể ngăn chặn nó.
Các bài viết liên quan:
Giới thiệu về Async trong Dart
Trong ngôn ngữ lập trình Dart, async
được sử dụng để xử lý các tác vụ bất đồng bộ. Điều này cho phép các chương trình Dart thực thi các tác vụ mà không cần chờ đợi các tác vụ khác hoàn thành trước đó.
async
là một từ khóa trong Dart, nó cho phép hàm trả về một Future
. Future
là một đối tượng có thể giúp xử lý các tác vụ bất đồng bộ. Khi một Future
được trả về, nó sẽ trả về một giá trị hoặc một ngoại lệ (exception) tùy thuộc vào kết quả của tác vụ bất đồng bộ đã được thực thi.
Trong Dart, việc sử dụng async
và Future
cho phép lập trình viên thực hiện các tác vụ bất đồng bộ một cách dễ dàng và hiệu quả hơn.
Hãy hiểu ví dụ sau:
Ví dụ
import 'dart:io'; void main() { print("Enter your favorite car :"); // prompt for user input String? car = stdin.readLineSync(); // this is a synchronous method that reads user input print("The car is ${car}"); print("End of main"); }
Giải thích:
Trong đoạn mã trên, chúng tôi đã sử dụng readLineSync () , là phương thức đồng bộ . Nó có nghĩa là; việc thực thi tất cả các lệnh theo sau lệnh gọi phương thức readLineSync () sẽ bị chặn cho đến khi phương thức readLineSync () không hoàn thành việc thực thi.
Stdin.readLineSync () không thực thi gì cho đến khi nó nhận được đầu vào từ người dùng. Nó đợi người dùng nhập để thực thi thêm.
Sự khác biệt giữa Asynchronous và Synchronous
Hãy hiểu sự khác biệt giữa đồng bộ và không đồng bộ.
Trong khoa học máy tính, nếu chúng ta nói một chương trình cụ thể là đồng bộ, điều đó có nghĩa là nó đang đợi một sự kiện để thực thi thêm. Cách tiếp cận này được điều khiển với một demerit, nếu một phần của mã mất nhiều thời gian để thực thi, các khối tiếp theo thông qua một khối không liên quan sẽ bị chặn thực thi.
Đây là vấn đề chính của phương pháp tiếp cận đồng bộ. Một phần của chương trình có thể yêu cầu thực thi trước phần hiện tại, nhưng cách tiếp cận đồng bộ không cho phép điều đó.
Điều này không phù hợp với các máy chủ web, nơi mà yêu cầu phải độc lập với những người khác. Nó có nghĩa là, máy chủ web không đợi để hoàn thành việc thực hiện yêu cầu hiện tại, nó sẽ phản hồi lại yêu cầu từ những người dùng khác.
Máy chủ web phải chấp nhận yêu cầu từ người dùng khác trước khi thực hiện các yêu cầu trước đó.
Cách tiếp cận này được gọi là lập trình không đồng bộ. Lập trình không đồng bộ thường tập trung vào mô hình lập trình không chờ hoặc không chặn. Dart : async được tạo điều kiện để triển khai khối lập trình không đồng bộ trong tập lệnh Dart.
Ví dụ
Chúng tôi tạo một tệp với một vài tên và lưu tệp này dưới dạng names.txt và viết chương trình để đọc tệp này mà không làm chậm phần khác của mã.
- 1 , Peter
- 2 , John
- 3 , Tom
- 4 , Johnson
Hãy xem xét đoạn mã sau.
import "dart:async"; import "dart:io"; void main(){ File file1 = new File("C:\Users\DUC\Desktop\contact.txt"); Future<String> fs = file1.readAsString(); // returns a future object, it is an async method fs.then((data)=>print(data)); // once file is read, call back method is invoked print("End of main"); }
Đầu ra
End of main 1, Peter 2, John 3, Tom 4, Johnson
Sử dụng Future trong Dart
Trong Dart, Future được sử dụng để thực hiện các tác vụ bất đồng bộ. Future đại diện cho một giá trị sẽ trả về trong tương lai. Khi tác vụ bất đồng bộ được thực hiện, Future sẽ trả về kết quả của tác vụ đó.
Để sử dụng Future trong Dart, trước hết chúng ta cần định nghĩa một hàm bất đồng bộ sử dụng từ khóa “async” và “await”. Trong hàm bất đồng bộ này, chúng ta sẽ thực hiện tác vụ bất đồng bộ và trả về một Future. Sau đó, chúng ta có thể sử dụng phương thức “then” của Future để xử lý kết quả của tác vụ đó.
Ví dụ, chúng ta có thể sử dụng Future để tải một file từ internet như sau:
import 'dart:io'; void main() async { String url = 'https://example.com/file.txt'; HttpClient httpClient = new HttpClient(); HttpClientRequest request = await httpClient.getUrl(Uri.parse(url)); HttpClientResponse response = await request.close(); await response.pipe(File('file.txt').openWrite()); }
Trong ví dụ này, chúng ta sử dụng phương thức “await” để chờ đợi tác vụ bất đồng bộ trả về kết quả trước khi tiếp tục thực hiện các lệnh khác. Sau đó, chúng ta sử dụng phương thức “then” của Future để xử lý kết quả của tác vụ.
Xem thêm Hướng dẫn kết nối REST API trong Flutter
Dart async/await
Trong Dart, async/await là cú pháp giúp đơn giản hóa việc xử lý các tác vụ bất đồng bộ. Khi sử dụng async/await, các tác vụ bất đồng bộ sẽ được thực thi theo trình tự, giúp cho việc xử lý dễ dàng hơn và mã nguồn trở nên dễ hiểu hơn.
Để sử dụng async/await trong Dart, ta cần đặt từ khóa async
trước phương thức hoặc hàm, và sử dụng từ khóa await
để chờ đợi kết quả trả về từ tác vụ bất đồng bộ.
Ví dụ:
Future<void> main() async { print('Bắt đầu chương trình'); await thucThiTacVuBatDongBo(); print('Kết thúc chương trình'); } Future<void> thucThiTacVuBatDongBo() async { print('Bắt đầu tác vụ bất đồng bộ'); await Future.delayed(Duration(seconds: 2)); print('Kết thúc tác vụ bất đồng bộ'); }
Trong ví dụ trên, phương thức main
được đánh dấu bằng từ khóa async
, và ta sử dụng từ khóa await
để chờ đợi tác vụ bất đồng bộ được thực thi xong. Phương thức thucThiTacVuBatDongBo
cũng được đánh dấu bằng từ khóa async
, và ta sử dụng await
để chờ đợi việc Future.delayed
hoàn thành.
Hãy hiểu ví dụ sau:
Ví dụ 1
import 'dart:io'; Future<void> fetchData() async { print("Fetching data..."); await Future.delayed(Duration(seconds: 2)); print("Data fetched!"); } void main() { fetchData(); print("Doing other things..."); }
Trong ví dụ trên, chúng ta tạo một hàm fetchData()
đánh dấu với async
để biểu diễn rằng nó là một hàm bất đồng bộ. Hàm này gọi Future.delayed
để chạy một tác vụ bất đồng bộ trong 2 giây. Để đợi cho kết quả của tác vụ bất đồng bộ, chúng ta sử dụng từ khóa await
. Sau khi gọi fetchData()
, chúng ta có thể tiếp tục thực hiện các tác vụ khác trong chương trình.
Xem thêm Cài đặt Dart
Sử dụng Isolate trong Dart để xử lý bất đồng bộ
Trong Dart, Isolate là một đơn vị xử lý độc lập, tương tự như thread trong các ngôn ngữ khác. Tuy nhiên, Isolate khác với thread ở chỗ nó không chia sẻ bộ nhớ với các Isolate khác. Thay vào đó, Isolate trao đổi dữ liệu thông qua cơ chế gửi tin nhắn giữa chúng.
Sử dụng Isolate trong Dart có thể giúp ta tăng hiệu suất xử lý của ứng dụng bằng cách chia nhỏ các tác vụ lớn thành các tác vụ nhỏ hơn và thực hiện chúng song song trên nhiều Isolate.
Để sử dụng Isolate trong Dart, ta cần import thư viện dart:isolate
và sử dụng lớp Isolate
. Ta có thể tạo một Isolate mới bằng cách sử dụng phương thức Isolate.spawn()
và truyền vào một hàm thực thi.
Ví dụ sau đây minh họa cách sử dụng Isolate trong Dart để tính tổng của một danh sách số:
import 'dart:isolate'; void main() async { final numbers = List.generate(1000000, (index) => index + 1); final sum = await computeSum(numbers); print('Sum: $sum'); } Future<int> computeSum(List<int> numbers) async { final receivePort = ReceivePort(); await Isolate.spawn(_sumIsolate, receivePort.sendPort); final completer = Completer<int>(); receivePort.listen((result) { completer.complete(result); receivePort.close(); }); receivePort.sendPort.send(numbers); return completer.future; } void _sumIsolate(SendPort sendPort) { final receivePort = ReceivePort(); sendPort.send(receivePort.sendPort); receivePort.listen((numbers) { final sum = numbers.reduce((value, element) => value + element); sendPort.send(sum); receivePort.close(); }); }
Trong ví dụ này, ta sử dụng Isolate để tính tổng của một danh sách số được tạo ra bằng cách sử dụng phương thức List.generate()
. Ta tạo một Isolate mới bằng cách sử dụng Isolate.spawn()
và truyền vào hàm _sumIsolate()
. Hàm _sumIsolate()
sẽ nhận danh sách số từ Isolate gốc, tính tổng của chúng và gửi kết quả về Isolate gốc. Ta sử dụng ReceivePort
và SendPort
để truyền thông tin giữa các Isolate.