代码之家  ›  专栏  ›  技术社区  ›  flakes

当操作返回未来时如何使用putifastence

  •  0
  • flakes  · 技术社区  · 6 年前

    在我的课上,我正在加载一些文件,为了提高效率,我想创建一个线程安全的缓存。我在地图课上看到 putIfAbsent 方法,但它不接受 async 类型。也不确定这种结构一般是否安全使用。

    这就是我要做的事情的风格:

    final Map<String, String> _cache = new Map();
    
    Future<String> parse(final String name) async {
      _cache.putIfAbsent(name, () async { // this async is not allowed
        return await new File(name).readAsString();
      });
      return _cache[name];
    }
    

    因为我可以在参数上使用Async,所以我选择使用锁,但这会使代码更加冗长。

    final Lock _lock = new Lock();
    final Map<String, String> _cache = new Map();
    
    Future<String> parse(final String name) async {
      if (!_cache.containsKey(name)) {
        await _lock.synchronized(() async {
          if (!_cache.containsKey(name)) {
            _cache[name] = await new File(name).readAsString();
          }
        });
      }
    
      return _cache[name];
    }
    

    有人知道我如何简化这段代码吗,或者如果有更好的库可以用于线程安全缓存?

    1 回复  |  直到 6 年前
        1
  •  2
  •   lrn    6 年前

    “不允许这种异步”是什么意思?我看不出 putIfAbsent 代码,我相信它会起作用。 我看到的一个问题是缓存不是缓存未来,而是字符串。因为您的函数无论如何都返回一个未来,所以您最好将未来存储在缓存中。

    我写的是:

    final Map<String, Future<String>> _cache = new Map();
    
    Future<String> parse(final String name) =>
        _cache.putIfAbsent(name, () => File(name).readAsString());
    

    但除了修复 _cache 地图类型,实际上是相同的,它只是避免创建和等待一些额外的未来。