Flutter是單線程任務(wù)執(zhí)行模式嵌纲,默認(rèn)情況下只會(huì)在主線程運(yùn)行。那么碰到耗時(shí)操作如:網(wǎng)絡(luò)請(qǐng)求腥沽、圖片加載逮走、數(shù)據(jù)庫操作等,F(xiàn)lutter該如何處理呢巡球?
Dart提供了兩個(gè)關(guān)鍵詞來實(shí)現(xiàn)異步操作:async
和await
言沐,這兩個(gè)關(guān)鍵詞要配合使用,如:
loadData() async {
String dataURL = "https://jsonplaceholder.typicode.com/posts";
http.Response response = await http.get(dataURL);
setState(() {
widgets = json.decode(response.body);
});
}
上面是一個(gè)典型的網(wǎng)絡(luò)請(qǐng)求方法酣栈,使用async來表示loadData函數(shù)是一個(gè)異步操作险胰,當(dāng)運(yùn)行到await代碼時(shí),表示有任務(wù)需要等待矿筝,CPU會(huì)去調(diào)度執(zhí)行其他IO操作起便。過一段時(shí)間CPU通過事件循環(huán)會(huì)輪詢一次,看某個(gè)協(xié)程是否任務(wù)已經(jīng)處理完成窖维,有返回結(jié)果可以被繼續(xù)執(zhí)行榆综,如果可以被繼續(xù)執(zhí)行的話,則會(huì)沿著上次離開時(shí)指針指向的位置繼續(xù)執(zhí)行铸史,也就是await標(biāo)志的位置鼻疮,執(zhí)行后面的setState()刷新UI的操作;與iOS的異步操作有點(diǎn)類似琳轿。
使用async會(huì)返回一個(gè)Future
結(jié)果判沟,Future
也是Dart提供的一個(gè)關(guān)鍵詞耿芹,可以通過鏈?zhǔn)秸{(diào)用,后面追加then
來實(shí)現(xiàn)挪哄,如:
Future.delayed(Duration(seconds: 1), (){
int value = 10;
return value;
}).then((onValue){
onValue++;
print('value $onValue');
});
Dart提供了另一個(gè)對(duì)線程的實(shí)現(xiàn)方案:isolate
吧秕,由線程和獨(dú)立內(nèi)存構(gòu)成,isolate線程之間不共享內(nèi)存迹炼,并且不和主線程的內(nèi)存堆共享內(nèi)存砸彬,因此不能訪問主線程中的變量,或者使用 setState() 來更新 UI斯入。isolate可以很好的利用多核CPU砂碉,來進(jìn)行大量耗時(shí)任務(wù)的處理。isolate線程之間的通信主要通過port來進(jìn)行咱扣,這個(gè)port消息傳遞的過程是異步的绽淘。通過Dart源碼也可以看出,實(shí)例化一個(gè)isolate的過程包括闹伪,實(shí)例化isolate結(jié)構(gòu)體沪铭、在堆中分配線程內(nèi)存、配置port等過程偏瓤。
loadData() async {
ReceivePort receivePort = ReceivePort();
await Isolate.spawn(dataLoader, receivePort.sendPort);
// The 'echo' isolate sends its SendPort as the first message
SendPort sendPort = await receivePort.first;
List msg = await sendReceive(sendPort, "https://jsonplaceholder.typicode.com/posts");
setState(() {
widgets = msg;
});
}
// The entry point for the isolate
static dataLoader(SendPort sendPort) async {
// Open the ReceivePort for incoming messages.
ReceivePort port = ReceivePort();
// Notify any other isolates what port this isolate listens to.
sendPort.send(port.sendPort);
await for (var msg in port) {
String data = msg[0];
SendPort replyTo = msg[1];
String dataURL = data;
http.Response response = await http.get(dataURL);
// Lots of JSON to parse
replyTo.send(json.decode(response.body));
}
}
Future sendReceive(SendPort port, msg) {
ReceivePort response = ReceivePort();
port.send([msg, response.sendPort]);
return response.first;
}
好了杀怠,內(nèi)容就到這里,以后有更多發(fā)現(xiàn)再來補(bǔ)充厅克。若有問題赔退,歡迎指正~
希望與大家共勉!
參考:
https://flutterchina.club/flutter-for-ios/
http://www.reibang.com/p/54da18ed1a9e