, March 23, 2023

0 kết quả được tìm thấy

Dart 2.15 có gì mới?


  •   9 min reads
Dart 2.15 có gì mới?

9/12/2021 vừa qua, team Flutter và team phát triển ngôn ngữ Dart thông  báo cập nhật phiên bản mới. Ở bài viết này, chúng ta sẽ cùng nhau tìm hiểu chi tiết những tính năng vừa mới được cập nhật thêm ở phiên bản Dart 2.15. Cùng xem thử để xem có tính năng nào mà bạn đang "mong chờ" từ lâu đối với ngôn ngữ Dart hay không 😄.

Tóm tắt nhanh các tính năng nổi bật bao gồm:

  • Thêm phương thức khai báo constructor kiểu mới: tear-off.
  • Improve cách sử dụng kiểu enum với thư viện dart:core.
  • Thêm các tính năng mới hỗ trợ các publisher quản lý các package của mình trên Pub.dev.

1. Fast Concurrency với worker isolates

Các thiết bị hiện đại hiện nay với sự hỗ trợ rất nhiều từ những CPU siêu mạnh chứa nhiều core có thể chạy song song nhiều thread và tác vụ ngầm cùng một lúc. Đối với các chương trình được thực thi từ ngôn ngữ Dart, mặc định Dart runtime system sẽ chạy tất cả các code Dart trên 1 single core, sau đó ngôn ngữ có thể sử dụng thêm các core khác để thực hiện các tác vụ cấp bậc hệ thống (system level) như chạy async xử lý các input/output, call api, download file, v.v

Nhưng thông thường ứng dụng Flutter của bạn phải đồng thời chạy thực thi nhiều tác vụ cùng 1 lúc, chẳng hạn như bạn vào 1 màn hình bất kỳ. Khi vào màn hình đó, bạn cho Animation trong màn hình bắt đầu chuyển động nhưng đồng thời call api parse json lấy dữ liệu để hiện thì lên màn hình (tạm gọi việc này là tác vụ thêm). Nếu việc xử lý dữ liệu quá lâu, nó có thể dẫn đến làm lag UI hoặc tệ hơn là làm Animation chạy "giựt giựt" gây trải nghiệm không tốt với người dùng. Nếu bạn biết cách "moving" các tác vụ thêm của mình chạy trên 1 core tách biệt, Animation của bạn sẽ tiếp tục chạy trên main thread mà không phải bị những thứ khác làm phiền, đương nhiên điều này sẽ làm cho ứng dụng của bạn chạy Animation lúc nào cũng mượt mà cả  😄.

Concurrency của Dart dựa trên mô hình isolates - một đơn vị độc lập thực thi chương trình ở một nơi riêng biệt. Ở phiên bản 2.15, Dart đã thực hiện nhiều nâng cấp cho các isolates.

Team Dart bắt đầu bằng việc re-design và re-implement lại cách hoạt động của isolates bằng cách giới thiệu 1 khái niệm mới: isolate groups. Các isolate trong isolate group chia sẻ các cấu trúc internal data đại diện cho chương trình đang chạy. Điều này giúp cho chương trình của bạn chạy nhanh hơn 100 lần trong việc thêm mới 1 isolate vào group isolate hiện có bởi vì chương trình không cần phải khởi tạo lại cấu trúc data và chi phí bộ nhớ sử dụng cho isolate này giảm từ 10 đến 100 lần.

Chúng ta có thể truyền object từ isolate này sang isolate khác, nó có thể được sử dụng cho các worker isolate hoạt động khi chương trình cần phải thực hiện các tác vụ cần nhiều memory. Một ví dụ điển hình thường gặp khi sử dụng worker isolate là khi bạn call api để lấy dữ liệu, sau đó bạn parse cục data đó thành 1 object JSON Graph và object đó được đưa về cho main isolate. Ở các phiên bản trước Dart 2.15, các kết quả mà bạn nhận được phải thực hiện nghiệp vụ deep-copied, điều đó có thể làm cho UI của ứng dụng bị jank và giựt lag vì việc copy tiêu tốn nhiều chi phí để thực hiện.

Ở phiên bản này, các worker isolate có thể gọi hàm Isolate.exit() để truyền các các kết quả sau khi thực hiện xong thành các argument. Sau đó, Dart Runtime sẽ truyền các bộ nhớ chứa kết quả từ worker isolate sang main isolate mà không cần phải copy, và đặc biệt hơn là main isolate nhận được kết quả ngay tức thì. Team Dart đã cập nhật lại chức năng cho hàm compute() cho Flutter version 2.8 để có thể nhận được full sức mạnh từ bản cập nhật mới. Nếu bạn đang sử dụng hàm compute(), bạn sẽ thấy được sự khác biệt rõ rệt sau khi cập nhật Flutter lên phiên bản 2.8

Cuối cùng, Dart đã rework lại cơ chế "giao tiếp" của isolate. Việc làm lại này giúp cho việc chuyển đi các message có kích cỡ từ nhỏ đến vừa nhanh hơn gấp 8 lần. Và đặc biệt hơn là ở đầu nhận lúc nào cũng nhận được ở constant time. Ngoài ra, Dart giờ đây hỗ trợ việc truyền các "message" đa dạng hơn như bạn có thể truyền function types, closures, hoặc stacktrace object. Xem chi tiết tại đây.

Và để dễ dàng hơn trong việc tìm hiểu và sử dụng isolates, mọi người có thể xem thêm document về Concurreny trong Dart và cũng như tự tay làm các ví dụ ở link này.

2. Constructor tear-offs

Bạn có thể khởi tạo 1 function object, nó sẽ tham chiếu đến 1 function object khác, bằng cách sử dụng function name. Trong ví dụ ở dưới đây, dòng thứ hai trong hàm main() là cách bạn sử dụng chức năng trên khi bạn có thể tham chiếu g với m.greet.

class Greeter {
  final String name;
  Greeter(this.name);
  
  void greet(String who) {
    print('$name says: Hello $who!');
  }
}

void main() {
  final m = Greeter('Michael');
  final g = m.greet; // g holds a function pointer to m.greet.
  g('Leaf'); // Invokes and prints "Michael says: Hello Leaf!"
}

Tương tự như pointer function, tear-off function cũng xuất hiện rất nhiều khi bạn sử dụng ngôn ngữ Dart. Dưới đây là 1 ví dụ khi sử dụng kết hợp function foreach() để duyệt qua các phần tử  và pointer function.

final m = Greeter('Michael');
['Lasse', 'Bob', 'Erik'].forEach(m.greet);
// Prints "Michael says: Hello Lasse!", "Michael says: Hello Bob!",
// "Michael says: Hello Erik!"

Trước đây, trong một số trường hợp khi dựng layout với Flutter UI bạn sẽ thấy khá khó chịu vì ngôn ngữ Dart chưa support tear-off function. Nhưng kể từ Flutter 2.8 trở đi, khi bạn muốn xây dựng layout list Column Text, bạn có thể dễ dàng code như sau:

class FruitWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
        children: ['Apple', 'Orange'].map(Text.new).toList(),
    );
  }
}

Text.new refer đến hàm constructor mặc định của Text widget.

3. Một vài thay đổi khác

Trong lúc thực hiện contrucstor tear-off, team phát triển ngôn ngữ Dart nhận thấy có một vài vấn đề liên quan đến việc không đồng nhất được syntak hỗ trợ cho chức năng trên. Do đó, team đã có một vài điều chỉnh để nhất quán hơn như sau:

T id<T>(T value) => value;
var intId = id<int>; // New in 2.15.
int Function(int) intId = id; // Pre-2.15 workaround.

Ngoài ra, bạn còn có thể sử dụng generic function để khởi tạo non-generic function:

const fo = id; // Tear off `id`, creating a function object.
const c1 = fo<int>; // New in 2.15; error before.

Một thay đổi khác đó là syntak code để bạn define kiểu literals.

var y = List; // Already supported.
var z = List<int>; // New in 2.15.
var z = typeOf<List<int>>(); // Pre-2.15 workaround.

4. Improve enum trong thư viện dart:core

Giờ đây bạn đã có thể get được kiểu dữ liệu String đối với biến enum (I like it :v) bằng cách sau:

enum MyEnum {
  one, two, three
}

void main() {
  print(MyEnum.one.name);  // Prints "one".
}

Ngoài ra, bạn có thể look up giá trị enum từ kiểu dữ liệu String bằng cách:

print(MyEnum.values.byName('two') == MyEnum.two);  // Prints "true".

Cuối cùng, bạn có thể mapping qua lại giữa cặp giá trị enum & String.

final map = MyEnum.values.asNameMap(); 
print(map['three'] == MyEnum.three);  // Prints "true".

Bạn có thể tham khảo cách sử dụng ở link đây.

5. DartDevTools được thêm vào DartSDK luôn

Trước đây, công cụ hỗ trợ trong việc debug và theo dõi performance ứng dụng không nằm trong DartSDK. Nếu bạn muốn sử dụng, bạn phải tự download riêng. Nhưng ở thời điểm hiện tại, khi bạn download DartSDK, DartDevTools đã được tải chung với bộ DartSDK. Để tìm hiểu chi tiết cách sử DevTools với Dart command line, bạn có thể đọc thêm DevTools documentation.

6. Tính năng mới trên pub hỗ trợ cho các publisher

Tính năng mới đầu tiên được Dart 2.15 SDK thêm vào đó là security feature. Mục đích của tính năng này đó là giúp cho các publisher bảo vệ được các thông tin cá nhân, tránh việc sơ suất để lộ các thông tin nhạy cảm như keyAPI, cloud, credential,.. trước khi publish package lên trang Pub.dev

Mỗi ngày, có hàng nghìn thông tin bị leak trên Github và team phát triển ngôn ngữ Dart không muốn điều này xảy ra đối với bạn sau khi tìm hiểu và đọc được tài liệu này

Tính năng leak detection được thêm vào bên trong câu lệnh chạy pre-publish dart pub publish - giúp bạn validation lại mọi thứ. Nếu phát hiện ra các thông tin "bảo mật", chương trình sẽ không cho bạn publish và văng ra các warning message để bạn kiểm tra lại, ví dụ như:

Publishing my_package 1.0.0 to https://pub.dartlang.org:
Package validation found the following errors:
* line 1, column 1 of lib/key.pem: Potential leak of Private Key detected.
╷
1 │ ┌ - - -BEGIN PRIVATE KEY - - -
2 │ │ H0M6xpM2q+53wmsN/eYLdgtjgBd3DBmHtPilCkiFICXyaA8z9LkJ
3 │ └ - - -END PRIVATE KEY - - -
╵
* line 2, column 23 of lib/my_package.dart: Potential leak of Google OAuth Refresh Token detected.
╷
2 │ final refreshToken = "1//042ys8uoFwZrkCgYIARAAGAQSNwF-L9IrXmFYE-sfKefSpoCnyqEcsHX97Y90KY-p8TPYPPnY2IPgRXdy0QeVw7URuF5u9oUeIF0";

Trong trường hợp bạn muốn publish luôn các thông tin như private key chẳng hạn, bạn có thể khai báo file đó vào danh sách allowlist để chương trình bỏ qua.

Cập nhật tiếp theo đó là cho phép bạn loại bỏ các version bị lỗi đã publish trên trang Pub. Giả sử bạn vừa thêm mới 1 tính năng cho package của mình, sau khi publish nhưng bạn kiểm tra lại thì nó bị lỗi hoặc chạy không như mong muốn của bạn, thay vì trước đây phải cố gắng fix nhanh nhất có thể để cho những ai sử dụng package của bạn không gặp phải thì giờ đây bạn chỉ cần lên trang Admin của Pub và loại bỏ nó đi một cách nhẹ nhàng.

Tất nhiên sau khi bạn loại bỏ version đó đi, bạn sẽ thấy trong file pubspec.lock hiển thị câu warning message như sau khi chạy pub get:

$ dart pub get
Resolving dependencies…
mypkg 0.0.181-buggy (retracted, 0.0.182-fixed available)
Got dependencies!

Tóm lại

Theo quan điểm của mình (người viết), Dart 2.15 đã cập nhật rất nhiều các tính năng thú vị, có cả cái mình đang rất mong đợi đó là chuyển enum sang String. Giờ cũng là thời điểm cuối năm 2021 và mình tin rằng năm sau sẽ còn là một năm bùng nổ nữa của Flutter cũng như ngôn ngữ Dart. Cảm ơn bạn đã dành thời gian đọc bài viết này ^^.

Xem thêm bài viết gốc ở link đây.

Bài viết liên quan

Flutter Tutorial 2022: Giới thiệu Flutter Travel App

Trong series này, chúng ta sẽ cùng nhau thực hiện ứng dụng Travel App với một bản UI Design vô cùng đẹp mắt, thu hút có sẵn....

Flutter Tutorial 2022: Giới thiệu Flutter Travel App
Tổng hợp các Shortcuts, Extensions & Settings trong VSCode khi lập trình Flutter

Trong bài viết này, mình sẽ liệt kê cho bạn các shortcuts, extensions, setting mà bạn nên sử dụng để lập trình Flutter hàng ngày....

Tổng hợp các Shortcuts, Extensions & Settings trong VSCode khi lập trình Flutter
[Phần 1] Những extension cần thiết khi làm việc với Flutter trên VS Code

VS Code là 1 text editor tuyệt vời được phát triển bởi Mircosoft. Đây là một trong các công cụ được developer trên toàn thế giới yêu thích vì sự tiện lợi, dễ dùng và nó chứa hàng ngàn, thậm chí trăm ngàn các extension phục vụ cho bạn trong quá trình bạn phát triển phần mềm....

[Phần 1] Những extension cần thiết khi làm việc với Flutter trên VS Code
Flutter Design Patterns: 17 — Bridge

Tổng quan về Bridge design pattern và việc thực hiện nó trong Dart và Flutter...

Flutter Design Patterns: 17 — Bridge
Navigation 2.0 - Routing On Flutter Web

Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách Navigation 2.0 hoạt động với Web Flutter, cách chúng ta có thể xây dựng các trang web và đồng bộ hóa URL với các dự án Flutter Web của chúng ta....

Navigation 2.0 - Routing On Flutter Web
You've successfully subscribed to 200Lab Blog
Great! Next, complete checkout for full access to 200Lab Blog
Xin chào mừng bạn đã quay trở lại
OK! Tài khoản của bạn đã kích hoạt thành công.
Success! Your billing info is updated.
Billing info update failed.
Your link has expired.