本次使用純代碼+注釋的方式涮母,將各個(gè)知識(shí)都展示出來
下方代碼可以直接執(zhí)行,通過查看log來更加深入的了解躁愿,在最后有一些理論和自己的一些理解叛本。
/*
* 1,需要注意返回值,=>是return的簡(jiǎn)寫攘已,所以1炮赦、2、3的then是compute的后續(xù)样勃,所以是在多線程中執(zhí)行,無序的性芬。
* 2,Future和自己的then是一體的峡眶,必定會(huì)同步執(zhí)行,而scheduleMicrotask則是后續(xù)添加的所以最后執(zhí)行
*
* */
void combinText() {
Future(() => compute(comFunc, '1')).then((val) => print(val)); //1
Future(() => compute(comFunc, '2')).then((val) => print(val));
Future(() => compute(comFunc, '3')).then((val) => print(val));
Future(() {
compute(comFunc, '4');
return '4處理';
}).then((val) => print(val));
Future(() {
compute(comFunc, '5');
return '5處理';
}).then((val) => print(val));
Future(() {
compute(comFunc, '6');
return '6處理';
}).then((val) => print(val));
Future(() {
compute(comFunc, '7');
scheduleMicrotask(() {
print('8處理'); //2
});
return '7處理';
}).then((val) => print(val));
}
/*
* computeTest是Isolate的高層封裝
* */
void computeTest() {
//創(chuàng)建Port
ReceivePort port = ReceivePort();
compute(comFunc, '初始值').then((val) => print(val));
}
String comFunc(str) {
return '${str}處理';
}
/*
* Isolate 多線程
* Isolate 看起來更加像進(jìn)程.因?yàn)橛歇?dú)立的內(nèi)存空間!
* ReceivePort如果使用到變量植锉,變量是進(jìn)行深拷貝的值拷貝.內(nèi)部修改值并不會(huì)影響外部變量本身,不用擔(dān)心多線程的資源搶奪問題!不需要鎖!
* */
Future<void> IsolateTest() async {
//創(chuàng)建Port
ReceivePort port = ReceivePort();
//創(chuàng)建isolate
Isolate iso = await Isolate.spawn(isoFunc, port.sendPort);
port.listen((val) {
print('內(nèi)部a=$a');
a = val;
port.close();
iso.kill();
});
sleep(Duration(seconds: 1));
print('外部a=$a');
}
int a = 1;
void isoFunc(SendPort port) {
sleep(Duration(seconds: 1));
a = 200;
print(port);
port.send(100);
}
//開始 , 5, 3,6,8,7,1,4,10,2,9
void testFuture4() {
Future x1 = Future(() => null);
x1.then((value) {
print('6');
scheduleMicrotask(() => print('7'));
}).then((value) => print('8'));
Future x = Future(() => print('1'));
x.then((value) {
print('4');
Future(() => print('9'));
}).then((value) => print('10'));
Future(() => print('2'));
scheduleMicrotask(() => print('3'));
print('5');
}
/*
* scheduleMicrotask微任務(wù)
* 在同一方法體中微任務(wù)優(yōu)先級(jí)高于Future辫樱,
* */
void MicrotTest() {
print('進(jìn)入');
Future(() {
print('A');
scheduleMicrotask(() {
print('A ---- scheduleMicroTask');
});
return Future(() => print('A--Future'));
}).then((value) => print('A結(jié)束'));
scheduleMicrotask(() {
print('scheduleMicroTask');
});
}
/*
* Future異步組
* 在組中是按照同步執(zhí)行
* */
void FutureGroup() {
print('進(jìn)入');
Future.wait([
Future.sync(() {
sleep(Duration(seconds: 2));
print('結(jié)束1');
return '任務(wù)一';
}),
Future.sync(() {
sleep(Duration(seconds: 1));
print('結(jié)束2');
return '任務(wù)二';
}),
]).then((value) {
print(value);
});
print('結(jié)束');
}
/*
* Future也可以同步執(zhí)行
* */
void FutureSync() {
print('進(jìn)入');
Future.sync(() {
sleep(Duration(seconds: 1));
print('異步操作');
});
print('結(jié)束');
}
//future的優(yōu)先級(jí)比then低
/*
* Future執(zhí)行完之后, 會(huì)將涉及到的所有then進(jìn)行一次性添加
* */
void FutureThenOrder() {
Future(() {
sleep(Duration(seconds: 1));
return '第一個(gè)異步處理';
}).then((e) {
print(e);
return Future(() {
sleep(Duration(seconds: 1));
return '第二個(gè)異步處理';
});
}).then((e) {
print(e);
return '第一個(gè)異步處理2';
});
}
/*
* 1俊庇,F(xiàn)utureOr<T>表示可以返回一個(gè)Future對(duì)象或者是<T>實(shí)例
* 2狮暑,catchError在then前時(shí),無法阻止then的執(zhí)行,因?yàn)楫?dāng)前then實(shí)際上是在捕獲catcherror這個(gè)Future
* 3, catchError的閉包返回值是依附上一層的<T>,如果上一層沒有返回值辉饱,catcherror中的返回值需要單聲明變量后使用
* 4, 超時(shí)
* */
Future<void> throwError() async {
print('進(jìn)入');
Future future = Future(() {
//1
print('異步操作');
sleep(Duration(seconds: 1));
// return '異步完成';
throw Exception('出錯(cuò)了');
})
.then((val) {
print('第一次then:${val}');
return '第一次then結(jié)束';
})
.catchError((e) {
print('errpr:${e}');
return '錯(cuò)誤處理'; //3
})
.then((e) => print(e)) //2
.timeout(Duration(seconds: 1)); //4
print('結(jié)束');
}
/*
* 1,使用await以后下方所有代碼都將進(jìn)行同步執(zhí)行
* 2,async/await必須成對(duì)出現(xiàn)搬男,使用async進(jìn)行方法的修飾后返回值必須也是Future<T>
* */
Future<void> getParams1() async {
print('進(jìn)入');
await Future(() {
sleep(Duration(seconds: 1));
print('異步操作');
});
print('結(jié)束');
}
最后是自己對(duì)異步執(zhí)行的一些理解,比較零散彭沼,在此做個(gè)記錄缔逛。
就算是將上述代碼一一執(zhí)行,一定也會(huì)有一些不理解的地方,這就需要一些理論的支持褐奴。
這是從官網(wǎng)拿下來的圖按脚,圖中清楚的展示了各種任務(wù)的執(zhí)行順序。
圖中的解讀:
- 一切執(zhí)行都是從main函數(shù)開始敦冬。(有點(diǎn)廢話了辅搬。。脖旱。)
- 微任務(wù)的執(zhí)行優(yōu)先級(jí)是最高的堪遂,接下來才是事件隊(duì)列(future+then)
- 微任務(wù)、事件隊(duì)列在執(zhí)行完成后都會(huì)檢查是否還有其他任務(wù)夯缺,而且會(huì)從原路徑去檢查是否有微任務(wù)->是否有事件隊(duì)列的順序蚤氏,直到任務(wù)結(jié)束。
也就是說在任務(wù)的執(zhí)行過程中踊兜,又有新的任務(wù)添加竿滨,就會(huì)通過這種方式來執(zhí)行。 - 完成之后退出捏境。
- Future和then是一對(duì)屬于事件隊(duì)列中于游,必定會(huì)同步先后執(zhí)行,并不是在Future執(zhí)行完成后才去進(jìn)行添加的垫言。