「这是我参加11月更文应战的第25天,活动概况检查:2021最后一次更文应战」
在之前的文章中,咱们已经学习了Future异步编程和Isolate多线程的运用,今日咱们来看一下,怎么运用异步编程与多线程结合运用;
异步与多线程结合运用
咱们先来看一段代码:
void main() {
testIsoLoad();
}
void testIsoLoad() {
Future(() => compute(func, 123)).then((value) => print('1'));
Future(() => compute(func, 123)).then((value) => print('2'));
Future(() => compute(func, 123)).then((value) => print('3'));
Future(() => compute(func, 123)).then((value) => print('4'));
Future(() => compute(func, 123)).then((value) => print('5'));
}
func(int message) {}
运转工程,检查打印成果:
从打印成果咱们能够得到定论,这几个print操作时异步的,他是在子线程处理的;
可是依照咱们之前对Future的研讨,多个Future之间应该是同步的才对,那么为什么此处却变成了异步的呢?接下来,咱们在其他代码坚持不变的状况下,将testIsoLoad办法中的代码进行如下修正:
然后,咱们运转工程,看到一下打印成果:
正告咱们屡次运转项目,最后发现打印顺序都是1、2、3、4、5,那么这是为什么呢?怎样又变成了同步的呢?咱们仅仅只是将=>的调用方式换成了{},怎样代码的履行成果就不一样了呢?
需要注意的是,=>在调用的过程中,有将履行成果进行return操作的含义,也便是说=> compute(func, 123)的履行,会将compute(func, 123)的成果进行return操作,咱们来验证一下,将testIsoLoad办法修正如下:
运转成果如下:
屡次运转之后,发现成果并不是固定的,也便是说,咱们进行了return操作之后,同步的履行流程变成了异步的,这也验证了咱们上边所说的=>函数的调用方式会将成果进行return操作;
假如在Future中return了子线程的Future(compute是对Future的封装),那么其then将会处理子线程的异步使命;那么已然then是子线程的异步操作了,那么Future中的使命是什么状况呢?
咱们在Future中增加如下打印:
运转成果;
能够看到,尽管then处理的是子线程的异步使命,可是Future中仍然还是同步使命;
Future与微使命
咱们来看下边这样代码:
Future f = Future(() {
print('异步使命1');
scheduleMicrotask(() {
print('微使命1');
});
});
很明显,咱们都能才到履行成果是:异步使命先履行,然后履行微使命;
假如,咱们持续给f增加一个then办法呢?
Future f = Future(() {
print('异步使命1');
scheduleMicrotask(() {
print('微使命1');
});
});
f.then((value) {
print('微使命2');
});
此时的履行成果怎么呢?
成果是微使命2比微使命1先履行,这是由于then办法咱们能够看做和Future的使命是一个整体,也便是then办法(一个微使命)先增加进入队列,然后微使命1的微使命会增加到then办法后边,所以then办法先履行;
不仅仅如此,咱们再增加一个whenComplete办法检查打印成果:
Future f = Future(() {
print('异步使命1');
scheduleMicrotask(() {
print('微使命1');
});
});
f.whenComplete(() {
print('完成');
});
f.then((value) {
print('微使命2');
});
打印成果如下:
whenComplete也能够看做和Future的使命是一个整体,whenComplete和then会依照增加顺序履行;
异步与多线程的选择
那么究竟什么时分运用异步使命,什么时分运用多线程操作呢?
尽管Future是个异步使命,可是在Future中的耗时操作是会堵塞主线程的。看如下代码:
咱们在相机按钮的点击办法中增加了一个for循环来模拟耗时操作,能够从打印成果看到,当Future中的耗时操作开端履行之后,界面被堵塞,无法滑动!当耗时操作结束之后,才能进行滑动操作;
这个时分,咱们能够运用compute来操作:
将耗时操作放在compute的办法中,将不会堵塞主线程,此处能够直接运用compute,不必Future;
