如何在异步函数完成它在 dart 中的任务之前停止执行
How to stop execution until async function completes it's task in dart
我正在开发一个 flutter 应用程序,其中 Build 方法调用 fetchCitiesList 方法获取城市列表,它将 cities 变量设置为 cities.And 的列表 Build 方法使用它来制作 listtiles 列表。
var cities;
void fetchCitiesList () async {
var url = 'https://gnsyms.000webhostapp.com/cities.php';
var json;
var httpClient = new HttpClient();
try {
var req = await httpClient.getUrl(Uri.parse(url));
var res = await req.close();
if (res.statusCode == HttpStatus.OK) {
json = await res.transform(UTF8.decoder).join();
cities = JSON.decode(json);
}
} catch (exception) {
print(exception);
}
}
@override
Widget build(BuildContext context) {
final double systemTopPadding = MediaQuery.of(context).padding.top;
fetchCitiesList();
return new Scaffold(
appBar: new AppBar(
title: new Center( child: new Text(widget.title,textScaleFactor: 1.3,), ),
),
body: new Center(
child: new Column(
children: <Widget>[
new Padding(padding: new EdgeInsets.fromLTRB(0.0, 228.0, 0.0, 15.0) , child: new Text('Select A City',style:_biggerFont)),
new DropdownButton(
items: new List.generate(cities.length, (int index){
return new DropdownMenuItem(child: new Container(
child: new Center(
child:new Text(cities[index],textScaleFactor: 1.4,))
,width: 250.0,),value: cities[index],);
}),
value: city,
onChanged: (arg){
setState((){
city = arg;
print(arg);
});
}),
new Padding(padding: new EdgeInsets.fromLTRB(0.0, 15.0, 15.0, 0.0),
child : new IconButton(icon: new Icon(Icons.arrow_forward,color: Colors.blue,size: 60.0,),
onPressed: _produceHospitalCards)),
],
),
)
);
}
但它会导致以下 exception.So,如何在异步函数完成其任务之前停止执行。
The following NoSuchMethodError was thrown building MyHomePage(dirty, state:
I/flutter ( 7695): _MyHomePageState#ec54c):
I/flutter ( 7695): The getter 'length' was called on null.
I/flutter ( 7695): Receiver: null
I/flutter ( 7695): Tried calling: length
您应该使用 FutureBuilder
小部件。
这是来自 docs 的示例:
new FutureBuilder<String>(
future: _calculation, // a Future<String> or null
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none: return new Text('Press button to start');
case ConnectionState.waiting: return new Text('Awaiting result...');
default:
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
else
return new Text('Result: ${snapshot.data}');
}
},
)
关于你的情况:如果你将 fetchCitiesList()
return 作为城市列表,那么你可以从示例中调用 fetchCitiesList()
而不是 _calculation
,然后得到通过 snapshot.data
.
获取数据
希望这对您有所帮助。
我正在开发一个 flutter 应用程序,其中 Build 方法调用 fetchCitiesList 方法获取城市列表,它将 cities 变量设置为 cities.And 的列表 Build 方法使用它来制作 listtiles 列表。
var cities;
void fetchCitiesList () async {
var url = 'https://gnsyms.000webhostapp.com/cities.php';
var json;
var httpClient = new HttpClient();
try {
var req = await httpClient.getUrl(Uri.parse(url));
var res = await req.close();
if (res.statusCode == HttpStatus.OK) {
json = await res.transform(UTF8.decoder).join();
cities = JSON.decode(json);
}
} catch (exception) {
print(exception);
}
}
@override
Widget build(BuildContext context) {
final double systemTopPadding = MediaQuery.of(context).padding.top;
fetchCitiesList();
return new Scaffold(
appBar: new AppBar(
title: new Center( child: new Text(widget.title,textScaleFactor: 1.3,), ),
),
body: new Center(
child: new Column(
children: <Widget>[
new Padding(padding: new EdgeInsets.fromLTRB(0.0, 228.0, 0.0, 15.0) , child: new Text('Select A City',style:_biggerFont)),
new DropdownButton(
items: new List.generate(cities.length, (int index){
return new DropdownMenuItem(child: new Container(
child: new Center(
child:new Text(cities[index],textScaleFactor: 1.4,))
,width: 250.0,),value: cities[index],);
}),
value: city,
onChanged: (arg){
setState((){
city = arg;
print(arg);
});
}),
new Padding(padding: new EdgeInsets.fromLTRB(0.0, 15.0, 15.0, 0.0),
child : new IconButton(icon: new Icon(Icons.arrow_forward,color: Colors.blue,size: 60.0,),
onPressed: _produceHospitalCards)),
],
),
)
);
}
但它会导致以下 exception.So,如何在异步函数完成其任务之前停止执行。
The following NoSuchMethodError was thrown building MyHomePage(dirty, state:
I/flutter ( 7695): _MyHomePageState#ec54c):
I/flutter ( 7695): The getter 'length' was called on null.
I/flutter ( 7695): Receiver: null
I/flutter ( 7695): Tried calling: length
您应该使用 FutureBuilder
小部件。
这是来自 docs 的示例:
new FutureBuilder<String>(
future: _calculation, // a Future<String> or null
builder: (BuildContext context, AsyncSnapshot<String> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none: return new Text('Press button to start');
case ConnectionState.waiting: return new Text('Awaiting result...');
default:
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
else
return new Text('Result: ${snapshot.data}');
}
},
)
关于你的情况:如果你将 fetchCitiesList()
return 作为城市列表,那么你可以从示例中调用 fetchCitiesList()
而不是 _calculation
,然后得到通过 snapshot.data
.
希望这对您有所帮助。