【问题标题】:What are the pros and cons of async, when to and when not to use it and what other alternatives to callback are there?异步的优缺点是什么,何时使用和何时不使用它以及回调的其他替代方案是什么?
【发布时间】:2016-01-26 04:53:19
【问题描述】:

回调或异步方法或其他选项

回调瘟疫的解决方案是“await”和“async”或更具体的“dart:async”库。

现在,异步的成本是多少?
我们什么时候不应该使用它们?
还有什么其他选择?

下面是一个编码错误的非聚合物自定义元素,它在桌面环境中的作用类似于消息框。它给了我更少的大括号和括号,但要求调用者也是异步的或使用“show().then((v){print(v);});”模式。
我应该避免这样的模式吗?
回调更好吗?还是有更聪明的方法?

轮询版本

import 'dart:html';
import 'dart:async';
void init(){
  document.registerElement('list-modal',ListModal);
}
class ListModal extends HtmlElement{
  ListModal.created():super.created();
  String _modal_returns="";
  void set modal_returns(String v){
    ///use the modal_returns setter to
    ///implement a custom behaviour for
    ///the return value of the show method 
    ///within the callback you can pass on calling append .
    _modal_returns=v;
  }

  factory ListModal(){
    var e = new Element.tag('list-modal');
    e.style..backgroundColor="olive"
      ..position="absolute"
      ..margin="auto"
      ..top="50%"
      ..verticalAlign="middle";
    var close_b = new DivElement();
    close_b.text = "X";
    close_b.style..right="0"
      ..top="0"
      ..margin="0"
      ..verticalAlign="none"
      ..backgroundColor="blue"
      ..position="absolute";
    close_b.onClick.listen((_){
      e.hide();
    });
    e.append(close_b,(_)=>e.hide());
    e.hide();
    return e;
  }
  @override
  ListModal append(
      HtmlElement e,
      [Function clickHandler=null]
      ){
    super.append(e);
    if(clickHandler!=null) {
      e.onClick.listen(clickHandler);
    }else{
      e.onClick.listen((_){
        this.hide();
        _modal_returns = e.text;
      });
    }
    return this;
  }
  Future<String> show() async{
    _modal_returns = '';
    this.hidden=false;
    await wait_for_input();
    print(_modal_returns);
    return _modal_returns;
  }
  wait_for_input() async{
    while(_modal_returns=="" && !this.hidden){
      await delay();
    }
  }
  void hide(){
    this.hidden=true;
  }
  Future delay() async{
    return new Future.delayed(
        new Duration(milliseconds: 100));
  }
}

非轮询版本

响应 Günter Zöchbauer 的智慧(避免轮询),发布一个使用完成器的版本。一如既往地感谢 Günter Zöchbauer:

import 'dart:html';
import 'dart:async';
void init(){
  document.registerElement('list-modal',ListModal);
}
class ListModal extends HtmlElement{
  ListModal.created():super.created();
  String _modal_returns="";
  Completer _completer;
  void set modal_returns(String v){
    ///use the modal_returns setter to
    ///implement a custom behaviour for
    ///the return value of the show method.
    ///Use this setter within the callback for
    ///append. Always call hide() after
    ///setting modal_returns.
    _modal_returns=v;
  }

  factory ListModal(){
    var e = new Element.tag('list-modal');
    e.style..backgroundColor="olive"
      ..position="absolute"
      ..margin="auto"
      ..top="50%"
      ..verticalAlign="middle";
    var close_b = new DivElement();
    close_b.text = "X";
    close_b.style..right="0"
      ..top="0"
      ..margin="0"
      ..verticalAlign="none"
      ..backgroundColor="blue"
      ..position="absolute";
    close_b.onClick.listen((_){
      e.hide();
    });
    e.append(close_b,(_){e.hide();});
    e.hide();
    return e;
  }
  @override
  ListModal append(
      HtmlElement e,
      [Function clickHandler=null]
      ){
    super.append(e);
    if(clickHandler!=null) {
      e.onClick.listen(clickHandler);
    }else{
      e.onClick.listen((_){
        _modal_returns = e.text;
        this.hide();
      });
    }
    return this;
  }
  Future<String> show() async{
    _modal_returns = '';
    _completer = new Completer();
    this.hidden=false;
    return _completer.future;
  }
  void hide(){
    hidden=true;
    _completer?.complete(_modal_returns);
    _completer=null;
  }
}

【问题讨论】:

    标签: dart


    【解决方案1】:

    通常情况下,是否应该使用异步是毫无疑问的。通常人们会尽量避免它。一旦您调用异步 API,您的代码就会异步,您无法选择是否需要。 在某些情况下,故意将异步执行设为异步。例如,将大型计算分成较小的块,以免使事件队列无法处理。

    在服务器端,有几个 API 函数允许在同步和异步版本之间进行选择。关于何时使用哪个进行了广泛的讨论。我会查找并添加链接。

    使用async / await 而不是.then() 的缺点应该是最小的。

    • 支持async / await 的最小 Dart SDK 版本是 1.9.1
    • VM 需要在第一次执行代码之前进行一些额外的重写,但这通常可以忽略不计。

    您的代码似乎在进行轮询。

    wait_for_input() async {
      while(_modal_returns=="" && !this.hidden){
        await delay();
      }
    }
    

    如果可能,应该避免这种情况。 最好让 modal 自己管理它的隐藏状态(例如通过添加一个hide() 方法),这样它就不必轮询它是否被外部隐藏了。

    【讨论】:

    • 您好,感谢您的评论。没有澄清这一点是我的错,但问题是关于一般使用 'dart:async' 包而不是 async 和 await 关键字。特别是关于使用更少的回调和更多的异步方法是否更好以提高可读性。感谢您的编程技巧,是的,轮询看起来确实很丑。
    • dart:xxx "packages" 是 SDK 的一部分。每当您的代码执行 ansyc 操作时,请使用 dart:asyncFutureStream 以及 dart:async 中的所有其他内容都是为了让开发体验更加愉快。 Darts 的整个处理模型都是围绕它建立的。我没想到问题的这个方向,因为每个人都只是使用它。
    猜你喜欢
    • 2019-10-18
    • 2018-02-25
    • 2010-09-15
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 2011-01-28
    • 1970-01-01
    相关资源
    最近更新 更多