【问题标题】:Difference between a Future returning another Future and NotFuture 返回另一个 Future 和 Not 之间的区别
【发布时间】:2014-09-29 19:33:54
【问题描述】:

我正在阅读the "Avast, Ye Pirates" example,它非常有趣。但是,作为一名大学生(没有编程经验),要掌握 RETURNING a Future 的概念还是有些困难。

有什么区别

这个,

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

还有这个

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

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

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

我在“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;
}

【问题讨论】:

    标签: design-patterns return dart future


    【解决方案1】:

    不同之处在于 Dart 中的异步执行流程由一些内部行为维护。

    这个流程依赖于continuations和a continuations,当然也依赖于返回的结果。

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

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

    如果您不返回异步执行流(延续)的结果,那么您会破坏事件链,因为只有一种方法可以保持它的活动状态 - 返回延续的结果,其中包含有关所有情况的信息(包括例外)。

    当您中断链时,您会中断执行流程,并且由于对异常情况缺乏控制,您的执行行为将无法预测。

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

    实际上,“_”只是函数参数的名称(它是前面(前项)计算的结果)。您可以使用任何您喜欢的允许名称。

    所以,总结一下。

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

    【讨论】:

    • 非常清晰简洁的解释。谢谢 mezoni。
    猜你喜欢
    • 2017-09-21
    • 2021-10-27
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    • 2019-10-08
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多