异步的优点和缺点是什么,何时何时不使用它以及还有其他什么替代方法?

时间:2016-01-26 04:53:20

标签: dart

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

回调瘟疫的解决方案是“等待”和“异步”或更具体的'dart:async'库。

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

下面是一个编码严重的非聚合物自定义元素,在桌面环境中就像一个messageBox。它给了我更少的括号和括号,但要求调用者也是异步或使用“show()。然后((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ünterZöchbauer的智慧(避免民意调查),发布使用完成者的版本。非常感谢GünterZö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;
  }
}

1 个答案:

答案 0 :(得分:3)

通常毫无疑问是否应该使用异步。通常会试图避免它。只要您调用异步API,您的代码就会异步同步,而无法选择是否需要。 在某些情况下,异步执行是故意使异步。例如,将较大的计算拆分为较小的块,以使事件队列不被处理。

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

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

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

您的代码似乎在进行投票。

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

如果可能,应该避免这种情况。 最好让模态本身管理其隐藏状态(例如通过添加hide()方法),然后它不必轮询它是否从外部隐藏。