在任意时刻, 一个 CPU 核心上(processor)只可能运行一个进程

每一个进程可以包含多个线程,线程是执行操作的最小单元,因此进程的切换落实到具体细节就是正在执行线程的切换

Future


Future 表示一个异步的操作结果,用来表示一个延迟的计算,返回一个结果或者error,使用代码实例:

Future future = getFuture();

future.then((value) => handleValue(value))

.catchError((error) => handleError(error))

.whenComplete(func);

future可以是三种状态:未完成的返回结果值返回异常

当一个返回future对象被调用时,会发生两件事:

  • 将函数操作入队列等待执行结果并返回一个未完成的Future对象

  • 函数操作完成时,Future对象变为完成并携带一个值或一个错误

首先,Flutter事件处理模型为先执行main函数,完成后检查执行微任务队列Microtask Queue中事件,最后执行事件队列Event Queue中的事件,示例:

void main(){

Future(() => print(10));

Future.microtask(() => print(9));

print(“main”);

}

/// 打印结果为:

/// main

/// 9

/// 10

基于以上事件模型的基础上,看下Future提供的几种构造函数,其中最基本的为直接传入一个Function

factory Future(FutureOr computation()) {

_Future result = new _Future();

Timer.run(() {

try {

result._complete(computation());

} catch (e, s) {

_completeWithErrorCallback(result, e, s);

}

});

return result;

}

Function有多种写法:

//简单操作,单步

Future(() => print(5));

//稍复杂,匿名函数

Future((){

print(6);

});

//更多操作,方法名

Future(printSeven);

printSeven(){

print(7);

}

Future.microtask

此工程方法创建的事件将发送到微任务队列Microtask Queue,具有相比事件队列Event Queue优先执行的特点

factory Future.microtask(FutureOr computation()) {

_Future result = new _Future();

//

scheduleMicrotask(() {

try {

result._complete(computation());

} catch (e, s) {

_completeWithErrorCallback(result, e, s);

}

});

return result;

}

Future.sync

返回一个立即执行传入参数的Future,可理解为同步调用

factory Future.sync(FutureOr computation()) {

try {

var result = computation();

if (result is Future) {

return result;

} else {

// TODO(40014): Remove cast when type promotion works.

return new _Future.value(result as dynamic);

}

} catch (error, stackTrace) {

/// …

}

}

Future.microtask(() => print(9));

Future(() => print(10));

Future.sync(() => print(11));

/// 打印结果: 11、9、10

Future.value

创建一个将来包含value的future

factory Future.value([FutureOr? value]) {

return new _Future.immediate(value == null ? value as T : value);

}

参数FutureOr含义为T value 和 Future value 的合集,因为对于一个Future参数来说,他的结果可能为value或者是Future,所以对于以下两种写法均合法:

Future.value(12).then((value) => print(value));

Future.value(Future((){

return 13;

}));

这里需要注意即使value接收的是12,仍然会将事件发送到Event队列等待执行,但是相对其他Future事件执行顺序会提前

Future.error

创建一个执行结果为error的future

factory Future.error(Object error, [StackTrace? stackTrace]) {

/// …

return new _Future.immediateError(error, stackTrace);

}

_Future.immediateError(var error, StackTrace stackTrace)
_zone = Zone._current {

_asyncCompleteError(error, stackTrace);

}

Future.error(new Exception(“err msg”))

.then((value) => print(“err value: $value”))

.catchError((e) => print(e));

/// 执行结果为:Exception: err msg

Future.delayed

创建一个延迟执行回调的future,内部实现为Timer加延时执行一个Future

factory Future.delayed(Duration duration, [FutureOr computation()?]) {

/// …

new Timer(duration, () {

if (computation == null) {

result._complete(null as T);

} else {

try {

result._complete(computation());

} catch (e, s) {

_completeWithErrorCallback(result, e, s);

}

}

});

return result;

}

Future.wait

等待多个Future并收集返回结果

static Future<List> wait(Iterable<Future> futures,

{bool eagerError = false, void cleanUp(T successValue)?}) {

/// …

}

FutureBuilder结合使用:

child: FutureBuilder(

future: Future.wait([

firstFuture(),

secondFuture()

]),

builder: (context,snapshot){

if(!snapshot.hasData){

return CircularProgressIndicator();

}

final first = snapshot.data[0];

final second = snapshot.data[1];

return Text(“data $first $second”);

},

),

Future.any

返回futures集合中第一个返回结果的值

static Future any(Iterable<Future> futures) {

var completer = new Completer.sync();

void onValue(T value) {

if (!completer.isCompleted) completer.complete(value);

}

void onError(Object error, StackTrace stack) {

if (!completer.isCompleted) completer.completeError(error, stack);

}

for (var future in futures) {

future.then(onValue, onError: onError);

}

return completer.future;

}

对上述例子来说,Future.any snapshot.data 将返回firstFuturesecondFuture中第一个返回结果的值

Future.forEach

为传入的每一个元素,顺序执行一个action

static Future forEach(Iterable elements, FutureOr action(T element)) {

var iterator = elements.iterator;

return doWhile(() {

if (!iterator.moveNext()) return false;

var result = action(iterator.current);

if (result is Future) return result.then(_kTrue);

return true;

});

}

这里边action是方法作为参数,头一次见这种形式语法还是在js中,当时就迷惑了很大一会儿,使用示例:

Future.forEach([“one”,“two”,“three”], (element) {

print(element);

});

Future.doWhile

执行一个操作直到返回false

Future.doWhile((){

for(var i=0;i<5;i++){

print(“i => $i”);

if(i >= 3){

return false;

}

}

return true;

});

/// 结果打印到 3

以上为Future中常用构造函数和方法

在Widget中使用Future

Flutter提供了配合Future显示的组件FutureBuilder,使用也很简单,伪代码如下:

child: FutureBuilder(

future: getFuture(),

builder: (context, snapshot){

if(!snapshot.hasData){

return CircularProgressIndicator();

} else if(snapshot.hasError){

return _ErrorWidget(“Error: ${snapshot.error}”);

} else {

return _ContentWidget(“Result: ${snapshot.data}”)

}

}

)

Async-await


使用

这两个关键字提供了异步方法的同步书写方式,Future提供了方便的链式调用使用方式,但是不太直观,而且大量的回调嵌套造成可阅读性差。因此,现在很多语言都引入了await-async语法,学习他们的使用方式是很有必要的。

两条基本原则:

  • 定义一个异步方法,必须在方法体前声明 async

  • await关键字必须在async方法中使用

首先,在要执行耗时操作的方法体前增加async:

void main() async { ··· }

然后,根据方法的返回类型添加Future修饰

Future main() async { ··· }

现在就可以使用await关键字来等待这个future执行完毕

print(await createOrderMessage());

例如实现一个由一级分类获取二级分类,二级分类获取详情的需求,使用链式调用的代码如下:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

给大家分享一份移动架构大纲,包含了移动架构师需要掌握的所有的技术体系,大家可以对比一下自己不足或者欠缺的地方有方向的去学习提升;

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

66)]

[外链图片转存中…(img-rDN7ELNX-1712508121366)]

[外链图片转存中…(img-DjptvNmS-1712508121366)]

[外链图片转存中…(img-xvfIV2Ni-1712508121367)]

[外链图片转存中…(img-AAc5Hvpl-1712508121367)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

给大家分享一份移动架构大纲,包含了移动架构师需要掌握的所有的技术体系,大家可以对比一下自己不足或者欠缺的地方有方向的去学习提升;

[外链图片转存中…(img-YUTS0aws-1712508121367)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐