为大量听众优化的 ChangeNotifier 的替代方案?

Posted

技术标签:

【中文标题】为大量听众优化的 ChangeNotifier 的替代方案?【英文标题】:Alternative for ChangeNotifier that is optimized for large number of listeners? 【发布时间】:2020-04-18 06:38:48 【问题描述】:

ChangeNotifier 的 Flutter 文档说

ChangeNotifier 针对少量(一或两个)侦听器进行了优化。添加和删​​除监听器是 O(N),调度通知是 O(N²)(其中 N 是监听器的数量)。

如果我想设计一个有很多监听器(例如几十个监听器)的模型,是否可以在 Flutter 中使用替代类?

理想情况下,我正在寻找小于 O(N^2) 的东西来调度通知,其中 N 是侦听器的数量。

【问题讨论】:

你找过供应商吗? pub.dev/packages/provider 取决于你如何使用它,O(N^2) 的事情并不重要。以提供者为例,大多数时候只有一个监听器,所以没有影响 【参考方案1】:

有趣的是,当我查看最新的代码/文档时,现在已经优化了!

上面写着(2021.01):

添加监听器是 O(1),移除监听器和发送通知是 O(N)(其中 N 是监听器的数量)。

这样我们就可以愉快地使用它了。对!

为什么会这样:查看源代码

  void notifyListeners() 
    assert(_debugAssertNotDisposed());
    if (_listeners!.isEmpty)
      return;

    final List<_ListenerEntry> localListeners = List<_ListenerEntry>.from(_listeners!);

    for (final _ListenerEntry entry in localListeners) 
      try 
        if (entry.list != null)
          entry.listener();
       catch (exception, stack) 
        ...
      
    
  

我们看到它遍历侦听器并调用它们。

在过去,即使是颤振 1.21,source code 看起来像:

  void notifyListeners() 
    assert(_debugAssertNotDisposed());
    if (_listeners != null) 
      final List<VoidCallback> localListeners = List<VoidCallback>.from(_listeners!);
      for (final VoidCallback listener in localListeners) 
        try 
          if (_listeners!.contains(listener))
            listener();
         catch (exception, stack) 
          ...
        
      
    
  

如你所见,在过去有双循环(一个 for 循环 + 一个包含检查),而在新时代则没有。

【讨论】:

以上是关于为大量听众优化的 ChangeNotifier 的替代方案?的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 数据监听器ChangeNotifier

Flutter Listen 的 ChangeNotifier 类,它是 ChangeNotifier 的一个属性

Scala Swing 中的听众和反应

如何从 ChangeNotifier 导航?

实施 ChangeNotifier 与 StateNotifier

如何关闭 ChangeNotifier Provider Flutter 中的函数