如何在飞镖中实现具有异步初始化和空安全的单例?
How to implement a singleton with async initialisation and null safety in dart?
我需要一个用于共享首选项的单例,它具有异步初始化但也适用于空安全。通常我使用以下单例实现,但是拥有空安全的单例的最佳方法是什么?
class SharedPrefs {
static SharedPrefs _instance;
static Future<Null> _mutex;
static Future<SharedPrefs> getInstance() async {
if (_mutex != null) {
await _mutex;
}
var completer = Completer<Null>();
_mutex = completer.future;
if (_instance == null) {
_instance = SharedPrefs();
await _instance.init();
}
completer.complete();
_mutex = null;
return _instance;
}
SharedPreferences prefs;
SharedPrefs();
Future<SharedPrefs> init() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return this;
}
dynamic get(String key) {
return prefs.getString(key);
}
Future<bool> put(String key, dynamic value) async {
return await prefs.setString(key,value);
}
}
给你:
class SharedPreferencesProvider {
static SharedPreferencesProvider? _instance;
final SharedPreferences _sharedPreferences;
static Future<SharedPreferencesProvider> getInstance() async {
if (_instance == null) {
final sharedPreferences = await SharedPreferences.getInstance();
_instance = SharedPreferencesProvider._(sharedPreferences);
}
return _instance!;
}
SharedPreferencesProvider._(SharedPreferences sharedPreferences)
: _sharedPreferences = sharedPreferences;
init-first 单例
class Singleton {
late Map<String,String> obj;
Db._();
static Db? _instance;
static Db get inst => _instance ??= Db._();
init () async {
// await ...
obj = {'a': 1};
}
}
void main () async {
// put init first
await Db.inst.init();
// your other code
// your other code
print(Db.inst.obj);
// your other code
// your other code
}
我在所有语言中都使用这种方法,稳定且易于理解。
一个测试示例
db.dart
import 'package:mongo_dart/mongo_dart.dart' as Mongo;
class Db {
late Mongo.DbCollection test;
Db._();
static Db? _instance;
static Db get inst => _instance ??= Db._();
init () async {
var db = Mongo.Db("mongodb://localhost:27017/");
await db.open();
test = db.collection('test');
}
}
test.dart
import 'package:mj_desk_server/db.dart';
void main () async {
await Db.inst.init();
myApp();
}
myApp () async {
// do anything
// do anything
// do anything
print(await Db.inst.test.find().toList());
print('ok');
}
我需要一个用于共享首选项的单例,它具有异步初始化但也适用于空安全。通常我使用以下单例实现,但是拥有空安全的单例的最佳方法是什么?
class SharedPrefs {
static SharedPrefs _instance;
static Future<Null> _mutex;
static Future<SharedPrefs> getInstance() async {
if (_mutex != null) {
await _mutex;
}
var completer = Completer<Null>();
_mutex = completer.future;
if (_instance == null) {
_instance = SharedPrefs();
await _instance.init();
}
completer.complete();
_mutex = null;
return _instance;
}
SharedPreferences prefs;
SharedPrefs();
Future<SharedPrefs> init() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return this;
}
dynamic get(String key) {
return prefs.getString(key);
}
Future<bool> put(String key, dynamic value) async {
return await prefs.setString(key,value);
}
}
给你:
class SharedPreferencesProvider {
static SharedPreferencesProvider? _instance;
final SharedPreferences _sharedPreferences;
static Future<SharedPreferencesProvider> getInstance() async {
if (_instance == null) {
final sharedPreferences = await SharedPreferences.getInstance();
_instance = SharedPreferencesProvider._(sharedPreferences);
}
return _instance!;
}
SharedPreferencesProvider._(SharedPreferences sharedPreferences)
: _sharedPreferences = sharedPreferences;
init-first 单例
class Singleton {
late Map<String,String> obj;
Db._();
static Db? _instance;
static Db get inst => _instance ??= Db._();
init () async {
// await ...
obj = {'a': 1};
}
}
void main () async {
// put init first
await Db.inst.init();
// your other code
// your other code
print(Db.inst.obj);
// your other code
// your other code
}
我在所有语言中都使用这种方法,稳定且易于理解。
一个测试示例
db.dart
import 'package:mongo_dart/mongo_dart.dart' as Mongo;
class Db {
late Mongo.DbCollection test;
Db._();
static Db? _instance;
static Db get inst => _instance ??= Db._();
init () async {
var db = Mongo.Db("mongodb://localhost:27017/");
await db.open();
test = db.collection('test');
}
}
test.dart
import 'package:mj_desk_server/db.dart';
void main () async {
await Db.inst.init();
myApp();
}
myApp () async {
// do anything
// do anything
// do anything
print(await Db.inst.test.find().toList());
print('ok');
}