我正在尝试找出Dart中的异步/等待问题。我正在调用一小段http提取指令,并希望等待所有指令。我创建了此示例代码来演示该问题。
我希望看到“开始测试”,然后依次开始每个下载。然后,每个下载将以随机顺序完成,然后我将看到“最终测试”。但是我什至在开始下载之前就已经看到了“结束测试”。
请帮助我了解我在做错什么。
force_bytes(the_code.split("'")[1])
这是输出。
import 'dart:async';
import 'package:http/http.dart' as http;
class AsyncTest {
final _resourceList = [
{
'name': 'Test 1',
'url': 'https://jsonplaceholder.typicode.com/posts'
},
{
'name': 'Test 2',
'url': 'https://jsonplaceholder.typicode.com/comments'
},
{
'name': 'Test 3',
'url': 'https://jsonplaceholder.typicode.com/albums'
},
{
'name': 'Test 4',
'url': 'https://jsonplaceholder.typicode.com/photos'
},
{
'name': 'Test 5',
'url': 'https://jsonplaceholder.typicode.com/users'
},
];
void beginTest() async {
print('begin test');
await getAll();
print('end test');
}
Future<void> getAll() async {
_resourceList.forEach((resource) async {
print('begin ${resource['name']}');
final response = await http.get(resource['url']);
print('end ${resource['name']}');
});
}
}
答案 0 :(得分:0)
您在await
内部进行的getAll()
调用允许事件循环处理不同的路径。所以是的,所有早期事物(开始...)首先出现,而后来事物(结束...)以明显随机的顺序出现是有意义的。这是异步编程的固有特性。
答案 1 :(得分:0)
我希望每次下载后都能看到“开始测试” 按顺序开始。然后,每个下载将随机完成 命令,然后我会看到“最终测试”。但是我看到“最终测试” 甚至还没有开始下载。
那是因为(偶然)您要求异步调用在之后 Future<void> getAll() async {
_resourceList.forEach((resource) async {
print('begin ${resource['name']}');
final response = await http.get(resource['url']);
print('end ${resource['name']}');
});
}
:
getAll() function
具体来说,您的功能是:
_resourceList.forEach(...)
getAll()
async { ... }
功能for ...
回调的主体您有一些选择。如果您想使用回调,则可以使用Future.wait
或Future.forEach
,否则getAll()
将在退出Future<void> getAll() async {
for (var resource in _resourceList) {
print('begin ${resource['name']}');
final response = await http.get(resource['url']);
print('end ${resource['name']}');
}
}
-内置{{3 }}。
import React, {Component} from 'react';
import {View, TextInput, TouchableOpacity, Text} from 'react-native';
import {connect} from 'react-redux';
import actions from '../Redux/Action';
class tes extends Component{
constructor(props){
super(props)
}
render(){
return(
<View>
<TextInput placeholder="phone number"
keyboardType="number-pad"/>
<TouchableOpacity onPress={this.props.onLogin}>
<Text>login</Text>
</TouchableOpacity>
</View>
)
}
}
mapStateToProps = state => {
return {
number: state.phoneNumber
}
}
mapDispatchToProps = dispatch => {
return {
onLogin: (number) => {
dispatch(actions.setLoginNumber(number))
}
}
}
export default connect(mapStateToProps, mapDispatchToProps)(tes);
答案 2 :(得分:0)
forEach(callback)
忽略了callback
的返回值。
如果您使用for
循环,则await
会按预期工作:
Future<void> getAll() async {
for(var resource in _resourceList) {
print('begin ${resource['name']}');
final response = await http.get(resource['url']);
print('end ${resource['name']}');
}
}
或者让循环体同时执行,您可以使用
Future<void> getAll() async {
return Future.wait(_resourceList.map((resource) async {
print('begin ${resource['name']}');
final response = await http.get(resource['url']);
print('end ${resource['name']}');
}));
}
使用map
收集从回调返回的Future
,当它们全部完成(成功或错误)时,返回的Future
将完成。