所以我需要運行一些需要稍后獲取一些資料的代碼。
我想象它像:
voin runWithContext(void Function () fn, dynamic context) {
// ... magic
fn();
}
然后在 fn() 的呼叫堆疊中
void otherFn() {
dynamic context = getContext();
}
如果函式不是異步的,我們可以將背景關系存盤為全域變數,但支持的主要要求dart:async
我正在研究dart:mirrors和堆疊跟蹤,但我找不到系結一些資料的方法。
uj5u.com熱心網友回復:
您可以使用Zone來做到這一點。區域及其“區域變數”是創建在整個異步計算中保留的背景關系的規范方式)。
由于您希望單個全域函式訪問背景關系,因此它必須是無型別的(或以您需要的一種型別鍵入,但通常不可重用)。那我想重新考慮設計,但如果它適合你,我會這樣做:
import "dart:async";
/// Container for a mutable value.
class _Context {
dynamic value;
}
final _Context _rootContext = _Context();
R runWithNewContext<R>(R Function() body) =>
runZoned(body, zoneValues: {
#_context: _Context()..value = context,
});
dynamic get context => (Zone.current[#_context] ?? _rootContext).value;
set context(dynamic value) {
(Zone.current[#_context] ?? _rootContext).value = value;
}
如果你不需要可變性,你可以稍微簡化一下,但不會太多。
型別化且不可修改的替代方案類似于
class _Box { // Distinguishable from `null`, even if value is `null`
final Object? value;
_Box(this.value);
}
class ZoneStorage<T> {
final _Box _initialValue;
ZoneStorage(T initialValue) : _initialValue = _Box(initialValue);
R update<R>(T newValue, R Function() body) =>
runZoned(body, zoneValues: {this: _Box(newValue)});
T get value =>
(Zone.current[this] as _Box? ?? _initialValue).value as T;
}
這允許您創建多個獨立的區域存盤,例如:
var zs1 = ZoneStorage<int>(1);
var zs2 = ZoneStorage<String>("yup");
zs1.update(42, () {
print(zs1.value);
print(zs2.value);
});
zs2.update("yup yup yup", () {
print(zs1.value);
print(zs2.value);
});
uj5u.com熱心網友回復:
所以需要的是https://api.dart.dev/stable/2.17.3/dart-async/Zone-class.html
希望答案對其他人有所幫助
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/497270.html
標籤:镖
上一篇:共享偏好:值未實時或立即更新
