回调瘟疫的解决方案是“等待”和“异步”或更具体的'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;
}
}
答案 0 :(得分:3)
通常毫无疑问是否应该使用异步。通常会试图避免它。只要您调用异步API,您的代码就会异步同步,而无法选择是否需要。 在某些情况下,异步执行是故意使异步。例如,将较大的计算拆分为较小的块,以使事件队列不被处理。
在服务器端,有几个API函数允许在同步和异步版本之间进行选择。关于何时使用哪一个进行了广泛的讨论。我会查找并添加链接。
使用async
/ await
代替.then()
的缺点应该是最小的。
async
/ await
支持的最小Dart SDK版本为1.9.1 您的代码似乎在进行投票。
wait_for_input() async {
while(_modal_returns=="" && !this.hidden){
await delay();
}
}
如果可能,应该避免这种情况。
最好让模态本身管理其隐藏状态(例如通过添加hide()
方法),然后它不必轮询它是否从外部隐藏。