【问题标题】:In Flutter/Dart, using async function to assign values, will the variable using the old pointed instance if it's changed?在 Flutter/Dart 中,使用异步函数来赋值,如果变量改变了,是否会使用旧的指向实例?
【发布时间】:2020-11-04 23:53:49
【问题描述】:

情况很难描述,请看以下代码:

示例 A

  class DataStructure {
      String imageURL;
  }

  var _a = DataStructure();
  var _b = DataStructure();
  var _original_a = _a;
  var _original_b = _b;

  _uploadImg(PickedFile image) async {
    setState(() {
      _imgPath = image.path;
    });
    _a.imageURL = await _upload(_imgPath);
    _a = _b; // assign the _a pointing to another data instance(The assignment here is just an example, maybe it's triggered by user's input. No matter how it's triggered, it happened before the _upload function finished.)
  }

示例 B

  class DataStructure {
      String imageURL;
  }

  var _a = DataStructure();
  var _b = DataStructure();
  var _original_a = _a;
  var _original_b = _b;

  _uploadImg(PickedFile image) async {
    setState(() {
      _imgPath = image.path;
    });
    var resultVal = _upload(_imgPath);
    resultVal.then((val){
      _a.imageURL = val;
    });
    _a = _b; // assign the _a pointing to another data instance(The assignment here is just an example, maybe it's triggered by user's input. No matter how it's triggered, it happened before the _upload function finished.)
  }

在这两个例子中,返回的值是分配给_original_a.imageURL 还是_original_.imageURL?这里的正确目标是将其分配给_original_a.imageURL

我使用sleep() 使用类似且更简单的飞镖示例对其进行了测试(因为示例代码很难在生产环境中测试)。我认为在这两种情况下,结果都将分配给_original_a.imageURL。但我不能 100% 确定我的测试是正确的,我也不明白幕后实际发生了什么。有人可以帮帮我吗?

据我了解,在第一个示例中,因为有一个await 关键字,所以程序将等待_uploade() 函数运行。并且只有将_upload()的结果赋值给_a.imageURL后,程序才会执行_a = _b。

我不确定在第二个示例中会发生什么。由于没有await关键字,程序会在_upload()函数完成之前执行_a = _b吗?

【问题讨论】:

  • 哦,真的很抱歉,_currentItem 是一个错字。应该是_a。更新了问题。在第一个示例中,await 调用确保 _a = _b 在分配之后发生。我认为这是确保data[0].imageURL 得到结果的原因。但我不确定第二个例子。

标签: flutter asynchronous dart async-await


【解决方案1】:

我又做了一些测试,这是我对这个问题的结论:不,它不使用旧的指向实例。

假设_upload() 将返回字符串'abc'Future

在示例 A 中,_original_a.imageURL 具有新值 'abc'_original_a.imageURL 具有其原始值(在此示例中为 null。)

在示例 B 中,_original_a.imageURL 具有其原始值,但 _original_b.imageURL 具有新值 'abc'

为什么?

await 关键字在示例 A 中停止执行并等待 async 函数返回值。在示例 B 中,由于没有 await 关键字,_a = _b; 行立即执行,并且在执行之前的_a.imageURL = val;。当_upload() 在一段时间后完成时,then 块内的部分将被执行。但是此时,_a 指针已经更改为指向另一个实例(与_b_original_b 相同)。所以'abc' 现在分配给'_original_b'

【讨论】:

  • 示例 B 是未定义的行为。你永远无法真正预测它的结果。
猜你喜欢
  • 2018-06-06
  • 1970-01-01
  • 2021-01-05
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
  • 1970-01-01
  • 2015-05-15
相关资源
最近更新 更多