Arkts初识
空安全
默认情况下,ArkTS中的所有范例都是不可为空的,因此范例的值不能为空。这雷同于TypeScript的严格空值检查模式(strictNullChecks),但规则更严格。
在下面的示例中,所有行都会导致编译时错误:
可以为空值的变量定义为团结范例T | null。
非空断言运算符
后缀运算符“ !”可用于断言其操作数为非空。
应用于可空范例的值时,它的编译时范例变为非空范例。比方,范例将从T | null更改为T:
空值归并运算符
空值归并二元运算符??用于检查左侧表达式的求值是否即是null大概undefined。如果是,则表达式的结果为右侧表达式;否则,结果为左侧表达式。
换句话说,a ?? b等价于三元运算符(a != null && a != undefined) ? a : b。
在以下示例中,getNick方法如果设置了昵称,则返回昵称;否则,返回空字符串:
可选链
在访问对象属性时,如果该属性是undefined大概null,可选链运算符会返回undefined。
分析:getSpouseNick的返回范例必须为string | null | undefined,因为该方法大概返回null大概undefined。
可选链可以任意长,可以包罗任意数量的?.运算符。
在以下示例中,如果一个Person的实例有不为空的spouse属性,且spouse有不为空的nick属性,则输出spouse.nick。否则,输出undefined:
- //非空断言
- export class A{
- a:number=0
- }
- export function fc(aa:A|null){
- // aa?.a=9
- // console.log(`${aa!.a}`)
- console.log(`${aa?.a}`)//可选链
- }
- //空值合并运算符
- export function hb(str:string|null){
- // 三元运算符
- // return (str!=null && str!=undefined)?str:'asd'
- return str ?? 'asd'
- }
复制代码- import { A, fc, hb } from '../arkts/Null';
- import { promptAction } from '@kit.ArkUI';
- @Entry
- @Component
- struct NullPage {
- @State message: string = 'Hello World';
- build() {
- RelativeContainer() {
- Text(this.message)
- .id('NullPageHelloWorld')
- .fontSize(50)
- .fontWeight(FontWeight.Bold)
- .alignRules({
- center: { anchor: '__container__', align: VerticalAlign.Center },
- middle: { anchor: '__container__', align: HorizontalAlign.Center }
- })
- .onClick(()=>{
- let a:A=new A();
- fc(a)
- fc(null)
- // let str=hb(null)
- let str=hb('张三')
- promptAction.showToast({message:str})
- })
- }
- .height('100%')
- .width('100%')
- }
- }
复制代码 模块
- 程序可分别为多组编译单元或模块。
- 每个模块都有其自己的作用域,即,在模块中创建的任何声明(变量、函数、类等)在该模块之外都不可见,除非它们被显式导出。
- 与此相对,从另一个模块导出的变量、函数、类、接口等必须首先导入到模块中。
- 导出
- 可以使用关键字export导出顶层的声明。
- 未导出的声明名称被视为私闻名称,只能在声明该名称的模块中使用。
- 注意:通过export方式导出,在导入时要加{}。
静态导入
导入声明用于导入从其他模块导出的实体,并在当前模块中提供其绑定。导入声明由两部门组成:
- 导入路径,用于指定导入的模块;
- 导入绑定,用于定义导入的模块中的可用实体集和使用形式(限定或不限定使用)。
- 导入绑定* as A表现绑定名称“A”,通过A.name可访问从导入路径指定的模块导出的所有实体:
- 导入绑定{ ident1, …, identN }表现将导出的实体与指定名称绑定,该名称可以用作简单名称:
- 如果标识符列表定义了ident as alias,则实体ident将绑定在名称alias下:
动态导入
- 应用开辟的有些场景中,如果希望根据条件导入模块大概按需导入模块,可以使用动态导入取代静态导入。
- import()语法通常称为动态导入dynamic import,是一种雷同函数的表达式,用来动态导入模块。以这种方式调用,将返回一个promise。
- 如下例所示,import(modulePath)可以加载模块并返回一个promise,该promise resolve为一个包罗其所有导出的模块对象。该表达式可以在代码中的任意位置调用。
- 如果在异步函数中,可以使用let module = await import(modulePath)。
导入HarmonyOS SDK的开放能力
HarmonyOS SDK提供的开放能力(接口)也必要在导入声明后使用。可直接导入接口模块来使用该模块内的所有接口能力
顶层语句
顶层语句是指在模块的最外层直接编写的语句,这些语句不被包裹在任何函数、类、块级作用域中。顶层语句包括变量声明、函数声明、表达式等。
从HarmonyOS NEXT Developer Preview 1版本开始引入Kit概念。SDK对同一个Kit下的接口模块进行了封装,开辟者在示例代码中可通过导入Kit的方式来使用Kit所包罗的接口能力。此中,Kit封装的接口模块可检察SDK目录下Kit子目录中各Kit的定义。
通过导入Kit方式使用开放能力有三种方式:
- 方式一:导入Kit下单个模块的接口能力
- 方式二:导入Kit下多个模块的接口能力。
- 方式三:导入Kit包罗的所有模块的接口能力。
- 此中,“module”为别名,可自定义,然后通过该名称调用模块的接口。
2.方式三大概会导入过多无需使用的模块,导致编译后的HAP包太大,占用过多资源,请谨慎使用。
- 程序可分别为多组编译单元或模块。
- 每个模块都有其自己的作用域,即,在模块中创建的任何声明(变量、函数、类等)在该模块之外都不可见,除非它们被显式导出。
- 与此相对,从另一个模块导出的变量、函数、类、接口等必须首先导入到模块中。
- 导出
- 可以使用关键字export导出顶层的声明。
- 未导出的声明名称被视为私闻名称,只能在声明该名称的模块中使用。
- 注意:通过export方式导出,在导入时要加{}。
并发
- 并发是指在同一时间内,存在多个任务同时执行的情况。对于多核设备,这些任务大概同时在不同CPU上并行执行。对于单核设备,多个并发任务不会在同一时刻并行执行,但是CPU会在某个任务休眠或进行I/O操作等状态下切换任务,调度执行其他任务,提拔CPU的资源利用率。
- 为了提拔应用的响应速率与帧率,克制耗时任务对主线程的影响,ArkTS提供了异步并发和多线程并发两种处置惩罚策略。
- 异步并发是指异步代码在执行到肯定水平后会被停息,以便在未来某个时间点继承执行,这种情况下,同一时间只有一段代码在执行。ArkTS通过Promise和async/await提供异步并发能力,适用于单次I/O任务的开辟场景。
- 多线程并发允许在同一时间段内同时执行多段代码。在主线程继承响应用户操作和更新UI的同时,配景线程也能执行耗时操作,从而克制应用出现卡顿。ArkTS通过TaskPool和Worker提供多线程并发能力,适用于耗时任务等并发场景。
- 并发多线程场景下,不同并发线程间必要进行数据通信,不同种别对象的传输方式存在差异,包括拷贝或内存共享等。
异步并发 (Promise和async/await)
- Promise和async/await提供异步并发能力,是标准的JS异步语法。异步代码会被挂起并在之后继承执行,同一时间只有一段代码执行,适用于单次I/O任务的场景开辟,比方一次网络哀求、一次文件读写等操作。无需别的启动线程执行。
- 异步语法是一种编程语言的特性,允许程序在执行某些操作时不必等候其完成,而是可以继承执行其他操作。
Promise
- Promise是一种用于处置惩罚异步操作的对象,可以将异步操作转换为雷同于同步操作的风格,以方便代码编写和维护。Promise提供了一个状态机制来管理异步操作的不同阶段,并提供了一些方法来注册回调函数以处置惩罚异步操作的乐成或失败的结果。
- Promise有三种状态:pending(进行中)、fulfilled(已完成)和rejected(已拒绝)。Promise对象创建后处于pending状态,并在异步操作完成后转换为fulfilled或rejected状态。
- 最基本的用法是通过构造函数实例化一个Promise对象,同时传入一个带有两个参数的函数,通常称为executor函数。executor函数接收两个参数:resolve和reject,分别表现异步操作乐成和失败时的回调函数。
-
- 上述代码中,setTimeout函数模仿了一个异步操作,并在1秒钟后随机生成一个数字。如果随机数大于0.5,则执行resolve回调函数并将随机数作为参数传递;否则执行reject回调函数并传递一个错误对象作为参数。
- Promise对象创建后,可以使用then方法和catch方法指定fulfilled状态和rejected状态的回调函数。then方法可继承两个参数,一个处置惩罚fulfilled状态的函数,另一个处置惩罚rejected状态的函数。只传一个参数则表现当Promise对象状态变为fulfilled时,then方法会自动调用这个回调函数,并将Promise对象的结果作为参数传递给它。使用catch方法注册一个回调函数,用于处置惩罚“失败”的结果,即捕捉Promise的状态改变为rejected状态或操作失败抛出的非常。
-
- 上述代码中,then方法的回调函数接收Promise对象的乐成结果作为参数,并将其输出到控制台上。如果Promise对象进入rejected状态,则catch方法的回调函数接收错误对象作为参数,并将其输出到控制台上。
async/await
- async/await是一种用于处置惩罚异步操作的Promise语法糖,使得编写异步代码变得更加简单和易读。通过使用async关键字声明一个函数为异步函数,并使用await关键字等候Promise的解析(完成或拒绝),以同步的方式编写异步操作的代码。
- async函数是一个返回Promise对象的函数,用于表现一个异步操作。在async函数内部,可以使用await关键字等候一个Promise对象的解析,并返回其解析值。如果一个async函数抛出非常,那么该函数返回的Promise对象将被拒绝,并且非常信息会被传递给Promise对象的onRejected()方法
- 下面是一个使用async/await的例子,此中模仿了一个以同步方式执行异步操作的场景,该操作会在3秒钟后返回一个字符串。
-
- 在上述示例代码中,使用了await关键字来等候Promise对象的解析,并将其解析值存储在result变量中。
- 必要注意的是,由于要等候异步操作完成,因此必要将整个操作包在async函数中。除了在async函数中使用await外,还可以使用try/catch块来捕捉异步操作中的非常。
-
- import { asy, p } from '../arkts/Asyac';
- @Entry
- @Component
- struct AsyacPage {
- @State message: string = 'Hello World';
- build() {
- RelativeContainer() {
- Text(this.message)
- .id('AsyacPageHelloWorld')
- .fontSize(50)
- .fontWeight(FontWeight.Bold)
- .alignRules({
- center: { anchor: '__container__', align: VerticalAlign.Center },
- middle: { anchor: '__container__', align: HorizontalAlign.Center }
- })
- // .onClick(()=>{
- // asy()
- // })
- .onClick(()=>{
- p()
- .then(data=>{
- console.log(data.toString()+'-----1')
- return p()
- })
- .then(data=>{
- console.log(data.toString()+'-----1')
- // return p()
- })
- .catch((er:string)=>{
- console.log(er.toString()+'-----1')
- })
- })
- }
- .height('100%')
- .width('100%')
- }
- }
复制代码- export function p():Promise<number>{
- return new Promise((r,j)=>{
- setTimeout(() => {
- let num=Math.random()
- if(num>0.5){
- r(num)
- }else{
- j('拒绝:你是个傻逼')
- }
- }, 1000);
- })
- }
- export async function asy() {
- console.log('开始执行异步操作');
- try{
- let num1=await p()
- console.log(num1.toString());
- let num2=await p()
- console.log(num2.toString());
- }catch(error){
- console.log(error);
- }
- }
- // function a():string{
- // return 123
- // }
复制代码- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>异步</title>
- </head>
- <body>
- <script>
- // console.log('任务1');
- // setTimeout(() => {
- // console.log('任务2');
- // }, 2000);
- // console.log('任务3');
- // console.log('任务4');
- // console.log('任务5');
- // console.log('任务6');
- // console.log('任务7');
- // 生成10个随机数,每隔1秒生成一个 回调地狱
- // setTimeout(() => {
- // console.log(Math.random() + '');
- // setTimeout(() => {
- // console.log(Math.random() + '');
- // setTimeout(() => {
- // console.log(Math.random() + '');
- // setTimeout(() => {
- // console.log(Math.random() + '');
- // setTimeout(() => {
- // console.log(Math.random() + '');
- // }, 1000);
- // }, 1000);
- // }, 1000);
- // }, 1000);
- // }, 1000);
- //resolve成功 reject失败
- let p1=new Promise((resolve,reject)=>{
- //生成随机数,小于0.5失败,大于0.5成功
- let num=Math.random()
- if(num<0.5){
- reject('小于0.5')
- }else{
- resolve('成功:'+num)
- }
- });
- //try{}catch(e){}
- //then()用来处理resolve的数据 data成功后返回的数据
- p1
- .then(data=>{
- console.log(data);
- })
- .catch(err=>{
- console.log(err);
- })
- .finally(()=>{
- console.log('最终执行');
- })
- // 生成10个随机数,每隔1秒生成一个
- let p2=new Promise((r,j)=>{
- setTimeout(() => {
- r(Math.random())
- }, 1000);
- })
- p2
- .then(data=>{//处理成功
- console.log(data);
- //下一个要执行的异步操作
- return new Promise((r,j)=>{
- setTimeout(() => {
- r(Math.random())
- }, 1000);
- })
- },
- err=>{//处理失败
- console.log(err);
-
- }
- )
- .then(data=>{//接受的是上一个then的return的异步操作的结果
- console.log(data)
- })
- .catch(err=>{
- console.log(err);
- })
- //async函数 达到的效果是同步代码的效果
- //1.生成一个promise
- function p(){
- return new Promise((r,j)=>{
- setTimeout(() => {
- let num=Math.random()
- if(num>0.5){
- r(num)
- }else{
- j(-1)
- }
- }, 1000);
- })
- }
- //使用异步函数 es8
- async function asy() {
- console.log('开始执行异步操作');
- try{
- let num1=await p()
- console.log(num1);
- let num2=await p()
- console.log(num2);
- }catch(error){
- console.log(error);
-
- }
- }
- console.log('主线程任务开始');
- asy()
- // console.log('主线程任务1');
- // console.log('主线程任务2');
- // console.log('主线程任务3');
- // console.log('主线程任务4');
- // console.log('主线程任务5');
- // console.log('主线程任务6');
- </script>
- </body>
- </html>
复制代码 (num2);
}catch(error){
console.log(error);
- }
- }
- console.log('主线程任务开始');
- asy()
- // console.log('主线程任务1');
- // console.log('主线程任务2');
- // console.log('主线程任务3');
- // console.log('主线程任务4');
- // console.log('主线程任务5');
- // console.log('主线程任务6');
- </script>
复制代码 ```
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |