当前位置:网站首页>Dart: About zone
Dart: About zone
2022-07-03 12:01:00 【J_ D_ Chi】
List of articles
Write it at the front
stay 《Flutter actual combat 》 From this book Flutter Exception trapping section , How to catch asynchronous exceptions , It mentioned using Zone To deal with .
Zone Represents the scope of the environment in which a code is executed , For ease of understanding , Readers can translate Zone Analogy to a code execution sandbox , The sandbox is isolated from each other , Sandbox can capture 、 Block or modify some code behavior , Such as Zone Log output can be captured in 、Timer establish 、 Behavior of micro task scheduling , meanwhile Zone You can also catch all unhandled exceptions .
This article is mainly right Zone Understand some usage and parameters .
Content
Let's start with the abnormal example
stay Flutter in , Catch and use exceptions in synchronization code try-catch
Conduct . We use it await
The way to deal with Future
, It is also synchronous code , So it can also be try-catch
Capture :
main() async {
try {
throw "My Error";
} catch (e) {
print(e);
}
try {
await Future.error("My Future Error");
} catch (e) {
print(e);
}
}
Print the results :
My Error
My Future Error
For asynchronous errors that are not written synchronously , So we need to go through Zone
To deal with it .Zone
Provides an environment for code , And can capture the relevant information inside . With 《Flutter actual combat 》 An example given in the book , It passes through Dart Inside runZoned()
Method , Let the current Zone fork A new Zone come out , Put the code inside and execute .
R runZoned<R>(R body(),
{Map<Object?, Object?>? zoneValues,
ZoneSpecification? zoneSpecification,
@Deprecated("Use runZonedGuarded instead") Function? onError}) {
checkNotNullable(body, "body");
...
return _runZoned<R>(body, zoneValues, zoneSpecification);
}
R _runZoned<R>(R body(), Map<Object?, Object?>? zoneValues,
ZoneSpecification? specification) =>
Zone.current
.fork(specification: specification, zoneValues: zoneValues)
.run<R>(body);
It can be seen that runZoned()
Is to Zone.current.fork().run()
An encapsulation of .
So by giving us the whole App Put on a Zone, You can catch all exceptions .
runZoned(() {
runApp(MyApp());
}, onError: (Object obj, StackTrace stack) {
var details=makeDetails(obj,stack);
reportError(details);
});
Zone
main
When we run main()
Function , In fact, it has been running in a root Of Zone in :
main() {
Zone.root.run(() => print("hello"));
print(Zone.root == Zone.current);
}
Print the results :
hello
true
stay main()
Call inside Zone.root.run()
The method follows directly main()
There is no difference in , And because it has been running by default , So we can't be right Zone
Make some custom modifications , That's why we want to build a new one Zone
To deal with it .
Parameters
Zone There are several parameters in :
- zoneValues
- zoneSpecification
- onError
zoneValues
This is a Zone Private data for , You can use the instance zone[key] obtain , And you can be yourself fork The one who came out Zone Inherit .
Zone parentZone = Zone.current.fork(zoneValues: {"parentValue": 1});
Zone childZone = parentZone.fork();
// childZone Through the father's key Get the corresponding value
childZone.run(() => {print(childZone["parentValue"])});
zoneSpecification
Zone Some configuration of , Some code behaviors can be customized , For example, blocking log output behavior .
abstract class ZoneSpecification {
...
const factory ZoneSpecification(
{HandleUncaughtErrorHandler? handleUncaughtError,
RunHandler? run,
RunUnaryHandler? runUnary,
RunBinaryHandler? runBinary,
RegisterCallbackHandler? registerCallback,
RegisterUnaryCallbackHandler? registerUnaryCallback,
RegisterBinaryCallbackHandler? registerBinaryCallback,
ErrorCallbackHandler? errorCallback,
ScheduleMicrotaskHandler? scheduleMicrotask,
CreateTimerHandler? createTimer,
CreatePeriodicTimerHandler? createPeriodicTimer,
PrintHandler? print,
ForkHandler? fork}) = _ZoneSpecification;
...
}
modify print Behavior
For example, in a Zone in , We want to modify its print Behavior , You can do this :
main() {
Zone parentZone = Zone.current.fork(specification: new ZoneSpecification(
print: (Zone self, ZoneDelegate parent, Zone zone, String line) {
parent.print(zone, "Intercepted: $line");
// You can also write the print into the file here , Send to the server
}));
parentZone.run(() => print("hello"));
print("hello");
}
Print the results :
Intercepted: hello
hello
You can see when we parentZone
Once it's up and running ,print Our behavior has been modified .
Because of the last print Not in the same Zone in , So this print No change .
modify run act
If we want to enter run()
Do something while you're at home , Can :
main() {
Zone parentZone = Zone.current.fork(
specification: new ZoneSpecification(
run: <R>(self, parent, zone, f) {
print("Enter run");
return parent.run(zone, f);
}));
parentZone.run(() => print("hello"));
}
Print the results :
Enter run
hello
Modify registration callback
main() {
Zone.root;
Zone parentZone = Zone.current.fork(specification:
new ZoneSpecification(registerCallback: <R>(self, parent, zone, f) {
// Call the callback function we actually registered , The first time I came here f yes start(), The second time I came in end()
f();
return f;
}));
parentZone.run(() {
Zone.current.registerCallback(() => start());
print("hello");
Zone.current.registerCallback(() => end());
});
}
void start() {
print("start");
}
void end() {
print("end");
}
Print the results :
start
hello
end
onError
although runZoned()
There are methods onError
The callback , But in the official new edition, it is recommended to use runZonedGuarded()
Instead of :
runZonedGuarded(() {
throw "null";
}, (Object error, StackTrace stack) {
print("error = ${error.toString()}");
});
Print the results
error = null
That is to say Zone
Those exceptions that we didn't catch in , Will go to onError
Callback .
So if this Zone
Of specification
It's done in handleUncaughtError
Or to achieve onError
Callback , So this Zone
It becomes a error-zone
.
that error-zone
Exceptions that occur in will not cross the border , for example :
var future = new Future.value(499);
var future2 = future.then((_) {throw "future error";});
runZonedGuarded(() {
var future3 = future2.catchError((e) {
print(e.toString()); // Don't print
});
}, (Object error, StackTrace stack) {
print(" error = ${error.toString()}"); // Don't print
});
future
Function in error-zone
The outer definition of , And it defines that an exception will be thrown after execution , When in error-zone
When calling in , At this time, this exception cannot be error-zone
Captured , Because it has exceeded its boundary , The solution is to define future
There is another function Zone
, In this way, this mistake will be outside error-zone
Captured :
var future = new Future.value(499);
runZonedGuarded(() {
var future2 = future.then((_) {
throw "future error";
});
runZonedGuarded(() {
var future3 = future2.catchError((e) {
print(e.toString());
});
}, (Object error, StackTrace stack) {
print(" error = ${error.toString()}");
});
}, (Object error, StackTrace stack) {
print("out error = ${error.toString()}");
});
Output results :
out error = future error
边栏推荐
- Concurrent programming - singleton
- mysql使用update联表更新的方法
- 错排问题 (抽奖,发邮件)
- vulnhub之presidential
- (database authorization - redis) summary of unauthorized access vulnerabilities in redis
- Symlink(): solution to protocol error in PHP artisan storage:link on win10
- Redis notes 01: Introduction
- PHP Basics
- Pragma pack syntax and usage
- Dynamically monitor disk i/o with ZABBIX
猜你喜欢
随机推荐
Is BigDecimal safe to calculate the amount? Look at these five pits~~
The uniapp scroll view solves the problems of high adaptability and bullet frame rolling penetration.
DNS多点部署IP Anycast+BGP实战分析
Systemverilog-- OOP--对象的拷贝
Differences between MySQL Union and union all
Oracle advanced (I) realize DMP by expdp impdp command
Solution to the second weekly test of ACM intensive training of Hunan Institute of technology in 2022
Niuniu's team competition
The tutor put forward 20 pieces of advice to help graduate students successfully complete their studies: first, don't plan to take a vacation
(构造笔记)从类、API、框架三个层面学习如何设计可复用软件实体的具体技术
[learning notes] DP status and transfer
简单工厂和工厂方法模式
Web security summary
Qt OpenGL相机的使用
网络通讯之Socket-Tcp(一)
Introduction to the implementation principle of rxjs observable filter operator
R language uses data The table package performs data aggregation statistics, calculates window statistics, calculates the median of sliding groups, and merges the generated statistical data into the o
同事写了一个责任链模式,bug无数...
Hongmeng fourth training
shardingSphere分库分表<3>