10.空安全
默认情况下,Arkts中的所有类型都是不可为空的,因此类型的值不能为空

以下情况编译会报错

let x:number=null; // 编译报错
let y:string=null;// 编译报错
let z:number[]=null;// 编译报错
如果避免上述情况可以使用联合类型

let x:number|null=null
x=1
x=null

(1)非空断言
后缀运算符使用 ! 可用于断言其操作不为空

如果运行时值非空则通过,如果值为空,则发生运行时的异常

class A{
    a:number=0
}
 
function fc(aa:A|null){
    console.log(`${aa!.a}`)
}

(2)空值合并运算符
空值合并二元运算符:?? 用于检查左侧表达式的求值是否等于null或者undefined如果是,则表达式的结果为右侧表达式:否则,结果为左侧表达式。

举个例子: a ?? b 等价与三元运算符(a !=null && a != undefined ? a:b)

function hb(str:string|null){
  // return (str!=null && str!=undefined)?str:'asf'
  return str ?? "asd"
}

(3)可选链
在访问对象属性时,如果该属性是undefined或者null,可选链运算符会返回undefined

class A{
  a:number=0
}
 
function fc(aa:A|null ) {
 
  console.log(`${aa?.a}`); // 可选链
}

11.模块
(1)导出
程序可划分为多组编译单元或模块,每个模块都有其自己的作用域。

在模块中创建的任何声明(变量、函数、类等)在该模块之外都不可见,除非它们被显示导出

导出使用关键字  export 导出顶层的声明

未导出的声明被视为私有名称,只能在声明该名称的模块

export class A{
    a:number=0
}

(2)导入
导入声明用于导入从其他模块导出的实体,并在当前模块中提供其绑定

导入声明由两部分组成:

1.导入路径:用于指定导入的模块;

2.导入绑定:用于定义导入的模块中的可用实体集和使用形式

import { A as a, fc, hb } from '../arkts/Nulls';
import { promptAction } from '@kit.ArkUI';
12.并发
 并发是指在同一时间内,存在多个任务同时执行。对于多核设备,这些任务可能同时在不同cpu上并行执行。对于单核设备,多个并发任务不会在同一时刻并发执行。

为了提升应用的响应速度与帧率,避免了耗时任务对主线程的影响,Arkts提供了异步并发和多线程并发两种处理策略。

异步并发是指异步代码在执行到一定程度后会被暂停,以便在未来某个时间点继续执行。这种情况下,同一时间只有一段代码在执行。ArkTS通过Promise和async/await提供异步并发能力,适用于单次I/O任务的开发场景。  

(1)异步并发
Promise和async/await提供异步并发能力,是标准的JS异步语法。异步代码会被挂起并在之后继续执行,同一时间只有一段代码执行。

异步语法是一种编程语言的特性,允许程序在执行某些操作时不必等待其完成,而是可以继续执行其他操作。

(2)promise
Promise是一种用于处理异步操作的对象,可以将异步操作转换为类似于同步操作的风格,以方便代码编写和维护。Promise提供了一个状态机制来管理异步操作的不同阶段,并提供了一些方法来注册回调函数以处理异步操作的成功或失败的结果。

Promise有三种状态:pending(进行中)、fulfilled(已完成)和rejected(已拒绝)。Promise对象创建后处于pending状态,并在异步操作完成后转换为fulfilled或rejected状态。

// 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)
            }
        });
 
     // then()用来处理resolve的数据  data成功后返回的数据
     p1
      .then(data=>{
         console.log(data);
      })
      .catch(err=>{
         console.log(err);
      })
      .finally(()=>{
         console.log('最终执行')
      })

最基本的用法是通过构造函数实例化一个Promise对象,同时传入一个带有两个参数的函数,通常称为executor函数。executor函数接收两个参数:resolve和reject,分别表示异步操作成功和失败时的回调函数。

Promise对象创建后,可以使用then方法和catch方法指定fulfilled状态和rejected状态的回调函数。then方法可接受两个参数,一个处理fulfilled状态的函数,另一个处理rejected状态的函数。只传一个参数则表示当Promise对象状态变为fulfilled时,then方法会自动调用这个回调函数,并将Promise对象的结果作为参数传递给它。使用catch方法注册一个回调函数,用于处理“失败”的结果,即捕获Promise的状态改变为rejected状态或操作失败抛出的异常

(3)async/await
async/await是一种用于处理异步操作的Promise语法,使得编写异步代码变得更加简单和易读。通过使用async关键字声明一个函数为异步函数,并使用await关键字等待Promise的解析(完成或拒绝),以同步的方式编写异步操作的代码。

async函数是一个返回Promise对象的函数,用于表示一个异步操作。在async函数内部,可以使用await关键字等待一个Promise对象的解析,并返回其解析值。如果一个async函数抛出异常,那么该函数返回的Promise对象将被拒绝,并且异常信息会被传递给Promise对象的onRejected()方法

// async函数 达到的效果是同步代码的效果
//1.生成一个promise  es6
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()

由于要等待异步操作完成,因此需要将整个操作包在async函数中。除了在async函数中使用await外,还可以使用try/catch块来捕获异步操作中的异常

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐