【问题标题】:Does notifyListeners() sometimes complete asynchronously?notifyListeners() 有时会异步完成吗?
【发布时间】:2019-05-25 12:33:10
【问题描述】:

我在返回 Future 的类的末尾调用 notifyListeners(),就在 return 语句之前。 notifyListeners 发起的动作在调用 return 和处理后续语句之前没有完全完成,导致错误。似乎 notifyListeners 以某种方式异步完成。

我在另一个论坛上询问过这个问题,并被告知这是一个常见的颤振错误,尤其是在动画方面。在我看来,我更有可能在语法上做错了什么。有没有人遇到过这个“错误”?

我尝试同时使用 .then() 和 async / await。两者的结果相同。

Future<bool> updateProduct(Map<String, dynamic> updatedProduct)

...

return http
    .put(
        'https://chocolate-f3e81.firebaseio.com/products/${newProduct.serverID}.json',
        body: json.encode(newProductMap))
    .then<bool>((http.Response response) {
  if (response.statusCode == 200 || response.statusCode == 201) {
    _products[selectedProductIndex] = newProduct;
    setIsLoading(false);
    print('model selectedProductIndex ${selectedProductIndex}');
    print('model selectedProductServerID ${_selectedProductServerID}');
     notifyListeners();
    return true;

我希望 notifyListeners() 启动的所有操作都在执行“return true”之前完成。这不会发生,而是执行返回操作,其他代码继续执行并领先于由 notifyListeners() 启动的代码。

【问题讨论】:

    标签: flutter


    【解决方案1】:

    没有。同步调用.then 的唯一方法是使用SynchronousFuture,这是未来的自定义重新实现。

    如果不是,那么即使未来立即完成,调用也是异步的。

    【讨论】:

      【解决方案2】:

      事实上,notifyListeners() 实际上会异步运行,因为它通过使用scheduleMicrotask() 调用所有已注册的侦听器来调度微任务。

      根据official documentation

      通过这个函数注册的回调总是在 顺序并保证在其他异步事件之前运行(例如 计时器事件或 DOM 事件)。

      只想到一个可能适用于您的情况的ugly 解决方案,即在return true 之前运行await Future.delayed(Duration(milliseconds: 300)),以便给它一点时间来完成其任务。

      【讨论】:

      • 谢谢,这是一个聪明而有见地的回应。由此我得出结论, notifyListeners() 不是一种非常可靠的实现方式,这是相当令人失望的。我想知道为什么它以这种方式工作是否有好处,或者是否有任何“修复”它的计划。我试图了解何时以及为什么应该使用 notifyListeners(),以及更可靠的替代方案可能是什么。这似乎是一个根本性的问题,我无法想象不会一直遇到这个问题。再次感谢您,您的回答是 100% 的目标。非常感谢任何进一步的建议。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-22
      • 2018-04-07
      • 1970-01-01
      • 2018-10-19
      • 2012-08-10
      相关资源
      最近更新 更多