等待未来函数完成其执行
Posted
技术标签:
【中文标题】等待未来函数完成其执行【英文标题】:Wait for a future function to complete its execution 【发布时间】:2020-10-11 06:15:30 【问题描述】:我是 Flutter 新手,在下面的代码中,第 18 行调用了读取数据函数(它执行 Firebase 数据库操作)我希望 readData() 函数必须先完成其执行转到打印语句(第 19 行)并进一步执行。
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:flutter/cupertino.dart';
import 'package:udharibook/Screens/SignInPage.dart';
import 'package:udharibook/Screens/UserProfile.dart';
import 'package:udharibook/Screens/dashboard.dart';
class AuthService
bool flag = false;
final FirebaseAuth _auth = FirebaseAuth.instance;
final DBRef = FirebaseDatabase.instance.reference().child('Users');
handleAuth()
return StreamBuilder(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (BuildContext, snapshot)
if(snapshot.hasData)
readData();
print(flag);
if(flag ==true)
return DashboardPage();
else
return UserProfile();
else
return SignIn();
,
);
Future<void> readData() async
final FirebaseUser user = await _auth.currentUser();
final userid = user.uid;
DBRef.child(userid).once().then((DataSnapshot data)
print(userid);
if(data.value!=null)
flag = true;
print(data.key);
print(data.value);
else
print('User not found');
flag = false;
);
signOut()
FirebaseAuth.instance.signOut();
signIn(AuthCredential authCreds)
FirebaseAuth.instance.signInWithCredential(authCreds);
signInWithOTP(smsCode,verId)
AuthCredential authCreds = PhoneAuthProvider.getCredential(
verificationId: verId,
smsCode: smsCode
);
signIn(authCreds);
【问题讨论】:
【参考方案1】:由于 readData() 是一个 AsyncFunction ,
在 readData() 之前添加关键字 await ,将强制 readData() 完成,然后打印,但是你不能这样做,因为 StreamBuilder正在等待 Widget 返回类型。
所以你能做的是 . 也许修改您的 readData 以返回 Future boolean readData() ;
Future<bool> readData() async
final FirebaseUser user = await _auth.currentUser();
final userid = user.uid;
DBRef.child(userid).once().then((DataSnapshot data)
print(userid);
if(data.value!=null)
print(data.key);
print(data.value);
return true;
else
print('User not found');
return false;
);
你叫它:
readData().then((value)
if (value ==true)
return Widget
else
return Widget;
);
希望对您有所帮助。
【讨论】:
设备屏幕出现错误:构建函数返回 null。违规小部件是:StreamBuilder如果您希望未来在构建/构建器方法中完成,那么使用FutureBuilder
是一个不错的方法。这样,您可以在未来完成时设置占位符小部件,然后在完成后输出所需的结果。在下面的示例中,我使用了一个圆形进度指示器作为占位符,但您可以使用任何小部件:
return StreamBuilder(
stream: FirebaseAuth.instance.onAuthStateChanged,
builder: (BuildContext, snapshot)
if(snapshot.hasData)
return FutureBuilder(
future: readData(),
builder: (context, futureSnapshot)
if (!futureSnapshot.hasData) return CircularProgressIndicator();
print(flag);
if(flag ==true)
return DashboardPage();
else
return UserProfile();
);
else
return SignIn();
,
);
【讨论】:
这意味着readData
函数存在问题。好像永远不会返回了,能不能先等待DBRef.child
,然后在下面插入一个return语句return Future.value()
?
通过返回 Future.value 进一步的代码变成了死代码并再次执行循环进度条以上是关于等待未来函数完成其执行的主要内容,如果未能解决你的问题,请参考以下文章