Function 异步函数依次返回两个不同的结果
我已经编写了一个异步颤振/飞镖函数,在我看来它的行为出人意料。以下代码结构:Function 异步函数依次返回两个不同的结果,function,flutter,dart,asynchronous,async-await,Function,Flutter,Dart,Asynchronous,Async Await,我已经编写了一个异步颤振/飞镖函数,在我看来它的行为出人意料。以下代码结构: static Future<bool> verifySometing() async { try { await getCloudData().then((snapshot) { if (snapshot.exists && snapshot.hasData) { bool dataValid = await validateDat
static Future<bool> verifySometing() async {
try {
await getCloudData().then((snapshot) {
if (snapshot.exists && snapshot.hasData) {
bool dataValid = await validateData(snapshot.data);
if (dataValid) {
print('Data is correct');
return true;
}
}
});
} catch (e) {
print('Error $e');
return false;
}
print('Something went wrong');
return false;
}
实际上,控制台显示以下输出,函数首先返回true,然后返回false:
Data is correct
Something went wrong
这与我想知道的关于Dart中函数的任何事情都是背道而驰的,因为我总是假设一旦触发了return,函数就完成了。你知道这是怎么发生的吗?问题在于这一行
await getCloudData().then((snapshot) {
在这里,您不仅添加了wait
ing,还附加了then
回调。所以实际上,无论返回什么,都是回调
函数的返回值,即(快照){}
您需要传递到中的回调函数,然后
将该返回true
并将其作为等待
的结果提供给我们
所以,如果你把
var bool = await getCloudData().then((snapshot) { ..... });
那么这个bool
,就等于true
。就这样。没有从主函数返回
换成这个,
var snapshot = await getCloudData();
if (snapshot.exists && snapshot.hasData) {
bool dataValid = await validateData(snapshot.data);
if (dataValid) {
print('Data is correct');
return true;
}
}
希望,我能解释清楚。你的假设中有一些错误 首先,您将
附加到getCloudData()
返回的future。这意味着您不是在等待getCloudData()
,而是等待getCloudData()返回的额外未来。然后(…)
,当传递给它的回调函数完成时,该未来将返回。(除非第一个future抛出错误,否则将调用回调。)
其次,回调函数在自己的作用域上运行。因此,这段代码并没有执行您认为它正在执行的操作:
booldatavalid=wait validateData(snapshot.data);
如果(数据有效){
打印(“数据正确”);
返回true;
}
此返回将影响回调函数,而不是verifySomething
函数
鉴于上述情况,操作顺序如下:
validateMething
函数wait
sgetCloudData()。然后(…)
getCloudData()
被调用
getCloudData()
返回,然后调用传递给的回调
(假设快照有数据)validateData
被调用
(假设数据已成功验证)打印“数据正确”,回调函数返回true
validateMething
被通知等待的未来已完成,因此继续执行
“出错”被打印出来,并且validateMething
函数返回false
一般来说,当混合async/await
和then
模式时,这类错误很常见。除非您知道自己在做什么,否则请坚持其中之一,最好是async/await
模式。例如,重构代码以消除对then
的调用,如下所示:
static Future verifySometing()异步{
试一试{
最终快照=等待getCloudData();
if(snapshot.exists&&snapshot.hasData){
bool dataValid=wait validateData(snapshot.data);
如果(数据有效){
打印(“数据正确”);
返回true;
}
}
}捕获(e){
打印('Error$e');
返回false;
}
打印(“出了问题”);
返回false;
}
既然没有麻烦的闭包需要处理,return
将按预期从validateMething
返回,您不需要处理回调和范围之类的问题。请记住,当您使用wait
时,您不需要使用then
,反之亦然。另外,await
停止代码的执行,同时释放线程用于其他工作,并且仅在等待的工作完成时继续。与和不同,后者不会停止下面代码的执行。
var snapshot = await getCloudData();
if (snapshot.exists && snapshot.hasData) {
bool dataValid = await validateData(snapshot.data);
if (dataValid) {
print('Data is correct');
return true;
}
}