回归另一个未来的未来之间的区别

时间:2014-08-06 18:32:30

标签: design-patterns return dart future

我正在阅读the "Avast, Ye Pirates" example,这非常有趣。但是,作为一名大学生(没有编程经验),掌握回归未来的概念有点困难。

之间有什么区别

此,

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

和这个

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

另一个问题:什么是(_)参数?为什么不只是一个空白的()。

在阅读Pirate示例后,我重新排列或重写了一些代码,将代码行数减少了三分之一或更少。虽然重新排列示例代码比阅读它更有趣,但我的代码变得越来越混乱,我的脑子也是如此。有没有关于如何在文件中安排类和函数等的Dart指南?也就是说,如何构建程序和文件的整个代码?不仅仅是MVC,还有一些详细的指导方针。下面是我的代码重写了Pirate示例。

我删除了“static void readyThePirates()”中的一些Future语法,但它仍然运行良好。

提前谢谢你。

// 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's 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;
}

1 个答案:

答案 0 :(得分:2)

差异在于Dart中的异步执行流由某些内部行为维护。

这个流依赖于延续,当然,延续依赖于返回结果。

此流程类似于事件链(不会将它们与其他事件混淆并从字面上理解它们)。

在这一系列事件中(在我们的现实生活中)可能会发生一些异常情况(例外)。

当你没有返回异步执行流程的结果(继续)时,你就打破了事件链,因为只有一种方法可以保持它活着 - 返回一个继续的结果,其中包含有关所有情况的信息(包括例外)。

当你打破链条时,你会破坏执行流程,并且由于缺乏对特殊情况的控制,你的执行行为将无法预测。

这意味着,如果在你的继续中(是的,异步操作只是一个延续)发生异常,你已经无法控制这种情况,因为当你不返回结果时你就失去控制(即使你不需要它并使用&#34; _&#34;)。

事实上,&#34; _&#34;只是函数参数的名称(这是先前(先行)计算的结果)。您可以使用您喜欢的任何允许名称。

所以,最后。

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);
}