已发布·持续改进
Dart 指南 · 6/6
本章目前仅提供英文版。
This chapter covers the ideas that make Dart feel like Dart: asynchronous code with Future, async/await and Stream; isolates; mixins and extension methods; and how they show up in Flutter.
Dart code runs in a single-threaded event loop inside an isolate. Slow operations such as file or network access do not block; they return a Future, a promise of a later value. Inside an async function, await lets you write code in order while the event loop handles other work.
Future<String> fetchUser(int id) async {
await Future.delayed(const Duration(milliseconds: 300)); // simulated network
return 'user$id';
}
Future<void> main() async {
print('start');
final user = await fetchUser(1);
print(user);
// Start several operations at once and wait for all of them
final users = await Future.wait([fetchUser(2), fetchUser(3)]);
print(users); // [user2, user3]
// Apply a time limit
try {
await fetchUser(4).timeout(const Duration(milliseconds: 100));
} catch (e) {
print('timed out: $e');
}
}An async function always returns a Future (Future<void> if there is no value). A dropped Future can swallow errors; when you deliberately skip await, mark it with unawaited() from dart:async.
A Stream is a sequence of values arriving over time, such as file chunks, WebSocket messages or input events. An async* function emits values with yield; consume them with await for or listen.
Stream<int> countdown(int from) async* {
for (var i = from; i > 0; i--) {
await Future.delayed(const Duration(milliseconds: 200));
yield i;
}
}
Future<void> main() async {
await for (final n in countdown(3)) {
print(n); // 3, 2, 1
}
final evensSquared = countdown(6)
.where((n) => n.isEven)
.map((n) => n * n);
final subscription = evensSquared.listen(
(value) => print('value: $value'),
onError: (Object e) => print('error: $e'),
onDone: () => print('done'),
);
await subscription.asFuture<void>();
}There are single-subscription streams, which can be listened to only once, and broadcast streams, which many listeners can share. When you need to push events yourself, use a StreamController.
async/await does not move CPU-heavy work to another core. Run expensive computations, such as parsing a huge JSON document, in an isolate. An isolate has its own memory and event loop and communicates only through messages, so there are no data races and no locks.
import 'dart:isolate';
int fib(int n) => n < 2 ? n : fib(n - 1) + fib(n - 2);
Future<void> main() async {
// Compute in a new isolate and receive the result
final result = await Isolate.run(() => fib(38));
print(result);
}Isolate.run runs a function in a new isolate and returns its result as a Future. For a long-lived worker, use Isolate.spawn with a ReceivePort and SendPort; Flutter also offers compute. Dart compiled for the web does not support isolates this way; use web workers there.
Dart uses single inheritance, but mixins let you plug the same behavior into several classes. Declare one with mixin and apply it with with. Adding on restricts a mixin to subclasses of a particular type.
Extension methods add methods or getters to existing types whose source you cannot change, such as String or List. Extensions are resolved statically, so they do not apply when a variable's static type is dynamic.
abstract class Animal {
String get name;
}
mixin Swimmer on Animal {
void swim() => print('$name is swimming');
}
mixin Flyer {
void fly() => print('taking off');
}
class Duck extends Animal with Swimmer, Flyer {
@override
final String name = 'Duck';
}
extension StringChecks on String {
bool get isBlank => trim().isEmpty;
String truncate(int max) => length <= max ? this : '${substring(0, max)}…';
}
void main() {
Duck()
..swim()
..fly();
print(' '.isBlank); // true
print('Dart language guide'.truncate(4)); // Dart…
}Since Dart 3.3 you can also use extension types, which wrap an existing type in a distinct static type with no run-time cost. They are mostly used for JavaScript interop and for giving values such as IDs their own type.
Every Flutter screen is Dart code. Widgets are Dart classes; named parameters keep widget trees readable, and const widgets are not rebuilt, which helps performance.
| Dart feature | What Flutter gets |
|---|---|
| JIT compilation during development | Stateful hot reload while you edit code |
| AOT native compilation for release | Fast startup and smooth rendering |
| JavaScript and WebAssembly compilation | Web apps from the same code base |
| Sound null safety | Fewer null errors at run time |
async/await and isolates | Networking and computation without freezing the UI |
Even without Flutter, Dart suits command-line tools, servers built with packages such as shelf, and web apps.
Dart handles asynchronous work with Future, async/await and Stream on top of a single-threaded event loop, and moves heavy computation to isolates that share no memory. Mixins and extension methods reuse behavior without inheritance, and together with JIT and AOT compilation these features make Flutter's hot reload and fast execution possible.
0 条评论
登录 · 登录后即可发表评论。
来发表第一条评论吧。