The difference between a future returning a different future and not

I am reading the example "Avast, Ye Pirates" and it is very interesting. But as a college student (no programming experience) it is somewhat difficult to grasp the concept of RETURN OF THE FUTURE.

What's the difference between

void doStuff() {
  someAsyncProcess().then((msg) => msg.result);
}

      

and this one

Future doStuff() {
  return someAsyncProcess().then((msg) => msg.result);
}

      

Another question: what is the (_) parameter? why not just empty ().

After reading the Pirate example, I rewrote or rewrote some of its codes, reducing the number of code lines by a third or less. While it's more fun to rearrange the example code than just read it, my codes got more and more jumbled, and so did my brains. Is there any Dart directive on how to organize classes and functions, etc. In file? That is, how to structure all program and file codes? not just MVC, but somewhat detailed guidelines. Below is my code rewriting Pirate's example.

I removed some Future syntax in "static void readyThePirates ()" but it still works well.

Thanks in advance.

// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import "dart:html";
import 'dart:math' show Random;
import 'dart:convert' show JSON;
import 'dart:async' show Future;


class PirateName {
  static final Random indexGen = new Random();

  static List<String> names = [];
  static List<String> appellations = [];


  String _firstName;

  String _appellation;

  PirateName({String firstName, String appellation}) {
    if (firstName == null) {
      _firstName = names[indexGen.nextInt(names.length)];
    } else {
      _firstName = firstName;
    }
    if (appellation == null) {
      _appellation = appellations[indexGen.nextInt(appellations.length)];
    } else {
      _appellation = appellation;
    }
  }

  PirateName.fromJSON (String jsonString) {
    Map storedName = JSON.decode(jsonString);
    _firstName = storedName['f'];
    _appellation = storedName['a'];

  }

  String get pirateName => _firstName.isEmpty ? '' : '$_firstName the $_appellation';

  String get jsonString => JSON.encode({
      "f": _firstName, "a": _appellation
  });

/* It original text in Avast example.
static Future readyThePirates() {
var path = 'piratenames.json';
return HttpRequest.getString(path)
    .then(_parsePirateNamesFromJSON);
}
*/
  static void readyThePirates() {
    var path = 'piratenames.json';
    Future future = HttpRequest.getString(path);
    future.then((String jsonString) {
      Map pirateNames = JSON.decode(jsonString);
      names = pirateNames['names'];
      appellations = pirateNames['appellations'];
    });
  }


}


final String TREASURE_KEY = 'pirateName';

void main() {
  getBadgeNameFromStorage();

  PirateName.readyThePirates();

  querySelector('#generateButton').onClick.listen(generateBadge);
  querySelector('#clearButton').onClick.listen(clearForm);
  querySelector('#jsonButton').onClick.listen(getBadgeNameFromJson);


}


void generateBadge(Event e){

  String inputName = querySelector('#inputName').value;
  var myPirate = new PirateName(firstName: inputName);

  querySelector('#badgeName').text = myPirate.pirateName;


  window.localStorage[TREASURE_KEY] = myPirate.jsonString;

  if (inputName.trim().isEmpty) {
    querySelector('#generateButton')
      ..disabled = false
      ..text = 'bra';
  } else {
    querySelector('#generateButton')
      ..disabled = true
      ..text = 'no bra';

  }
}

PirateName getBadgeNameFromStorage() {
  String storedName = window.localStorage[TREASURE_KEY];
  if (storedName != null) {
    PirateName newPirate = new PirateName.fromJSON(storedName);
    querySelector('#badgeName').text = newPirate.pirateName;
  } else {
    return null;
  }
}

void clearForm(Event e) {
    querySelector('#generateButton').disabled = false;
    querySelector('#badgeName').text = "";
    querySelector('#inputName').value = "";
}

void getBadgeNameFromJson(Event e) {
  var jsonPirate = new PirateName();


  querySelector('#badgeName').text = jsonPirate._firstName + ' the '+ jsonPirate._appellation;
}

      

+3


source to share


1 answer


The difference is that the asynchronous thread of execution in Dart is supported by some internal behavior.

This flow is continuation based, and continuation of course depends on the results returned.

This stream is like a chain of events (does not confuse them with other events and takes them literally).

In this chain of events (as in our real life), some exceptional situations (exception) may occur.

When you do not return the result of the asynchronous thread of execution (continuation), you break the chain of events, since there is only one way to keep it alive - return the result of the continuation, which contains information about all situations (including exceptional).

When you break the chain, you break the flow of execution, and the behavior of your execution will be unpredictable due to the lack of control over exceptions.



This means that if an exception occurs in your continuations (yes, asynchronous operations are just continuation), you no longer have control over the situation, because you lose control when you don't return a result (even if you don't need it and use it " _ ").

In fact, "_" is just the name of the function parameter (which is the result of the previous (prior) calculation). You can use any legal name you prefer.

So, in conclusion.

Future foo() {
  // You will lose control over the flow (chain of events)
  new Future(() => throw "Don't miss me, return this future");
}

      

Future foo() {
  // You pass control over the chain
  return new Future(() => throw "Don't miss me, return this future");
}

      

Future noUsefulResult() {
   return new Future.value(null);
}

Future<int> baz() {      
  // return noUsefulResult().then((_) => 42); 
  return noUsefulResult().then((INotNeedIt) => 42);
}

      

+2


source







All Articles