[官文翻译]Futter超快数据库Isar - 技巧 - 多 isolate (隔离)用法

502 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情


Isar:用于 Futter 可跨平台的超快数据库

官方文档:Home | Isar Database

pub:isar | Dart Package (flutter-io.cn)

本文翻译自:Multi-Isolate usage | Isar Database

译时版本:3.0.2


多隔离用法

代替线程,所有的 Dart 代码都运行中 isolate(隔离)内部。 每个 isolate 都有各自的内存堆,确保 isolate 中的 state 都不能在其它 isolate 中访问。

Isar 可以同时从多个 isolate 访问,即使监视器也能跨多个 isolate 运行。 该篇方法中,我们会看一下如何在多 isolate 环境中使用 Isar 。

什么时候使用多隔离

Isar 事务是平行执行的,即使是在相同的 isolate 中。 一些情况下,从多 isolate 中访问 Isar 也有好处。

理由是 Isar 从 Dart 对象编码数据和将数据解码为 Dart对象都很花时间。 可以认为和编码解码 JSON (只是更高效)差不多。 这些操作在 isolate 内部运行,从这里面,数据可以访问和自然地阻止 isolate 的其它代码。 换句话说:Isar 执行了 Dart isolate 中的一部分工作。

如果只是需要一次读写几百条对象,在 UI isolate 里做没什么问题。 但是如果有巨大的事务或者 UI 线程已经很繁忙,应该考虑使用单独的 isolate 。

示例

首先需要做的是在新的 isolate 中打开 Isar 。 因为 Isart 实例已经在主 isolate 中打开了,Isar.open() 会返回同一个实例。

确保在主 isolate 中提供了相同的 Schema 。否则会出错误。

compute() 在 Flutter 中开启一个新的 isolate 然后在其中运行给定的函数。

void main() {
  // 在 UI isolate 打开 Isar
  final isar = await Isar.open(
    [MessageSchema]
    name: 'myInstance',
  );

  // 监听数据库的变化
  isar.messages.watchLazy(() {
    print('omg the messages changed!');
  });

  // 开启新的 isolate 并创建 10000 个消息
  compute(createDummyMessages, 10000).then(() {
    print('isolate finished');
  });

  // 过些时间:
  // > omg the messages changed!
  // > isolate finished
}

// 将在新的 isolate 中执行的函数
Future createDummyMessages(int count) async {
  // 这里我们不需要路径,因为实例已经是打开的。
  final isar = await Isar.open(
    [PostSchema],
    name: 'myInstance',
  );

  final messages = List.generate(count, (i) => Message()..content = 'Message $i');
  // 我们在 isolate 中使用同步事务
  isar.writeTxnSync(() {
    isar.messages.insertAllSync(messages);
  });
}

上面的示例中有一些有趣的事情需要注意一下:

  • isar.posts.watchLazy() 是在 UI isolate 中被调用和通知的,即使消息是在其它 isolate 中被改变。
  • 实例通过名称来引用。默认的名称是 defaul ,但在该示例中我们设置成了 myInstance
  • 使用同步事务来创建消息。阻止新的 isolate 没有问题,同步事务会快一点儿。