简体   繁体   中英

In Flutter/Dart, using async function to assign values, will the variable using the old pointed instance if it's changed?

The situation is hard to describe, please see the following code:

Example 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.)
  }

Example 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.)
  }

In both examples, will the returned value assigned to _original_a.imageURL or _original_.imageURL ? The proper goal here is to assign it to _original_a.imageURL .

I've tested it using a similar and simpler dart example using sleep() (because the example codes are hard to test in production environment). I think in both cases the result will be assigned to _original_a.imageURL . But I'm not 100% sure that my test is correct, nor do I understand what actually happened behind the hood. Could someone help me please?

In my understanding, in the 1st example, because there's a await keyword, so the program will wait for _uploade() function to run. And only after the result of _upload() is assigned to _a.imageURL, the program will execute _a = _b.

I'm not sure what happens In the 2nd example. Since there's no await keyword, will the program execute _a = _b before the _upload() function finished?

I've made some tests again, and here's my conclusion to this quesiont: no, it does not use the old pointed instance.

Assuming that _upload() will return a Future of string 'abc' .

In example A, _original_a.imageURL has the new value 'abc' , _original_a.imageURL has its original value( null in this example.)

In example B, _original_a.imageURL has its original value, but _original_b.imageURL has the new value 'abc' .

Why?

await keyword stops the execution and wait for the async function to return a value in example A. In example B, since there's no await keyword, the _a = _b; line is executed immediately, and it's before the execution of _a.imageURL = val;. When the _upload() is finished after some time, the part within then block will be executed. However at this point, the _a pointer has already been changed to pointing another instance(same with _b and _original_b ). So the 'abc' is assigned to '_original_b' now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM