一、并发概述

并发是指在同一时间段内,能够处理多个任务的能力。为了提升应用的响应速度与帧率,以及防止耗时任务对主线程的干扰,HarmonyOS系统提供了异步并发和多线程并发两种处理策略。

● 异步并发是指异步代码在执行到一定程度后会被暂停,以便在未来某个时间点继续执行,这种情况下,同一时间只有一段代码在执行。

● 多线程并发允许在同一时间段内同时执行多段代码。在主线程继续响应用户操作和更新UI的同时,后台也能执行耗时操作,从而避免应用出现卡顿。

并发能力在多种场景中都有应用,其中包括单次I/O任务、CPU密集型任务、I/O密集型任务和同步任务等。开发者可以根据不同的场景,选择相应的并发策略进行优化和开发。

ArkTS支持异步并发和多线程并发。

● Promise和async/await提供异步并发能力,适用于单次I/O任务的开发场景。详细请参见异步并发概述

● TaskPool和Worker提供多线程并发能力,适用于CPU密集型任务、I/O密集型任务和同步任务等并发场景。详细请参见多线程并发概述

二、  使用异步并发能力进行开发

1、  异步并发概述

Promise和async/await提供异步并发能力,是标准的JS异步语法。异步代码会被挂起并在之后继续执行,同一时间只有一段代码执行,适用于单次I/O任务的场景开发,例如一次网络请求、一次文件读写等操作。

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

1.1 Promise

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

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

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

const promise = new Promise((resolve, reject) => {
setTimeout(() => {
const randomNumber = Math.random();
if (randomNumber > 0.5) {
resolve(randomNumber);
} else {
reject(new Error('Random number is too small'));
}
}, 1000);
});

  

上述代码中,setTimeout函数模拟了一个异步操作,并在1秒钟后随机生成一个数字。如果随机数大于0.5,则执行resolve回调函数并将随机数作为参数传递;否则执行reject回调函数并传递一个错误对象作为参数。

Promise对象创建后,可以使用then方法和catch方法指定fulfilled状态和rejected状态的回调函数。then方法可接受两个参数,一个处理fulfilled状态的函数,另一个处理rejected状态的函数。只传一个参数则表示状态改变就执行,不区分状态结果。使用catch方法注册一个回调函数,用于处理“失败”的结果,即捕获Promise的状态改变为rejected状态或操作失败抛出的异常。例如:

promise.then(result => {
console.info(`Random number is ${result}`);
}).catch(error => {
console.error(error.message);
});

  

上述代码中,then方法的回调函数接收Promise对象的成功结果作为参数,并将其输出到控制台上。如果Promise对象进入rejected状态,则catch方法的回调函数接收错误对象作为参数,并将其输出到控制台上。

1.2 async/await

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

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

下面是一个使用async/await的例子,其中模拟了一个异步操作,该操作会在3秒钟后返回一个字符串。

async function myAsyncFunction() {
const result = await new Promise((resolve) => {
setTimeout(() => {
resolve('Hello, world!');
}, 3000);
});
console.info(String(result)); // 输出: Hello, world!
} myAsyncFunction();

  

在上述示例代码中,使用了await关键字来等待Promise对象的解析,并将其解析值存储在result变量中。

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

async function myAsyncFunction() {
try {
const result = await new Promise((resolve) => {
resolve('Hello, world!');
});
} catch (e) {
console.error(`Get exception: ${e}`);
}
} myAsyncFunction();

  

2、  单次I/O任务开发指导

Promise和async/await提供异步并发能力,适用于单次I/O任务的场景开发,本文以使用异步进行单次文件写入为例来提供指导。

1.  实现单次I/O任务逻辑。

import fs from '@ohos.file.fs';

async function write(data: string, filePath: string) {
let file = await fs.open(filePath, fs.OpenMode.READ_WRITE);
fs.write(file.fd, data).then((writeLen) => {
fs.close(file);
}).catch((err) => {
console.error(`Failed to write data. Code is ${err.code}, message is ${err.message}`);
})
}

  

2.  采用异步能力调用单次I/O任务。示例中的filePath的获取方式请参见获取应用文件路径

let filePath = ...; // 应用文件路径
write('Hello World!', filePath).then(() => {
console.info('Succeeded in writing data.');
})

  

HarmonyOS如何使用异步并发能力进行开发的更多相关文章

  1. 异步IO的并发能力:backlog的配置很重要

    今天中午正准备完工的时候,发现一个让人抓狂的问题. 一个精简版的AIO应用理论上应该比一个完整版的AIO应用并发能力高一些(因为完整版的事务处理复杂一些),在同一台机器上测试. 但测试结果显示,精简版 ...

  2. 《连载 | 物联网框架ServerSuperIO教程》- 6.并发通讯模式开发及注意事项

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  3. 讨论django并发能力及提供并发解决方案

    django 的并发能力真的是令人担忧,这里就使用 nginx + uwsgi 提供高并发 nginx 的并发能力超高,单台并发能力过万(这个也不是绝对),在纯静态的 web 服务中更是突出其优越的地 ...

  4. 【Python】迭代器、生成器、yield单线程异步并发实现详解

    转自http://blog.itpub.net/29018063/viewspace-2079767 大家在学习python开发时可能经常对迭代器.生成器.yield关键字用法有所疑惑,在这篇文章将从 ...

  5. Python 开源异步并发框架的未来

    http://segmentfault.com/a/1190000000471602 开源 Python 是开源的,介绍的这几个框架 Twisted.Tornado.Gevent 和 tulip 也都 ...

  6. 异步并发利器:实际项目中使用CompletionService提升系统性能的一次实践

    场景 随着互联网应用的深入,很多传统行业也都需要接入到互联网.我们公司也是这样,保险核心需要和很多保险中介对接,比如阿里.京东等等.这些公司对于接口服务的性能有些比较高的要求,传统的核心无法满足要求, ...

  7. Python开源异步并发框架

    Python开源异步并发框架的未来 2014年3月30日,由全球最大的中文IT社区CSDN主办的“开源技术大会·” (Open Source Technology Conference ,简称OSTC ...

  8. python异步并发模块concurrent.futures入门详解

    concurrent.futures是一个非常简单易用的库,主要用来实现多线程和多进程的异步并发. 本文主要对concurrent.futures库相关模块进行详解,并分别提供了详细的示例demo. ...

  9. Node.js的那些坑——如何让异步并发方法同步顺序执行(for循环+异步操作)

    1 前言 nodejs的回调,有时候真的是让人又爱又恨的,当需要用for循环把数据依次存入数据库,但是如果使用正常的for循环,永远都是最后一次值的记录,根本不符合要求. 解决此方案有几种,例如闭包( ...

  10. JavaScript异步并发请求问题

    JavaScript异步并发请求问题 JS中如何处理多个ajax并发请求? jQuery的deferred对象详解 面试遇到的ajax请求串行和并行问题

随机推荐

  1. [C++逆向] 6 函数的工作原理

    目录 栈帧的形成和关闭 各种调用方式的考察 _stdcall _cdecl _fastcall 使用ebp或者esp寻址 某次调用函数时的栈结构 函数参数 不定长参数 函数的返回值 栈帧的形成和关闭 ...

  2. RocketMQ(1) 基础介绍和单机-集群安装

    1. MQ简单介绍 1.1 应用场景 应用解耦 系统的耦合性越高,容错性就越低.以电商应用为例,用户创建订单后,如果耦合调用库存系统.物流系统.支付系统,任何一个子系统出了故障或者因为升级等原因暂时不 ...

  3. C++ //统计元素个数 //统计内置数据类型 //统计自定义数据类型

    1 //统计元素个数 2 3 #include<iostream> 4 #include<string> 5 #include<vector> 6 #include ...

  4. Linux 网络编程从入门到进阶 学习指南

    前言 大家好,我是小康.在上一篇文章中,我们探讨了 Linux 系统编程的诸多基础构件,包括文件操作.进程管理和线程同步等,接下来,我们将视野扩展到网络世界.在这个新篇章里,我们要让应用跳出单机限制, ...

  5. Python | Flask 解决跨域问题

    Python | Flask 解决跨域问题 系列文章目录 目录 系列文章目录 前言 使用步骤 1. 引入库 2. 配置 1. 使用 CORS函数 配置全局路由 2. 使用 @cross_origin ...

  6. Vue + Element-ui实现后台管理系统(6)---权限管理思路讲解

    权限管理思路讲解 有关后台管理系统之前写过五篇博客,看这篇之前最好先看下这五篇博客.另外这里只展示关键部分代码,项目代码放在github上: mall-manage-system 1.Vue + El ...

  7. 9、Azure DevOps安装部署篇

    下载地址 微软默认提供了两个版本的下载:Azure DevOps Server和Azure DevOps Server Express . Azure DevOps Server 提供90天试用的收费 ...

  8. 视野修炼第71期 | Rspack 家族新成员 Rsdoctor

    欢迎来到第 71 期的[视野修炼 - 技术周刊],下面是本期的精选内容简 强烈推荐 Rspack 新成员:Rsdoctor Bun Shell DCloud:App跨平台框架对比2023版 开源工具& ...

  9. Spring Boot学习日记17

    尝试整合JDBC spring: datasource: username: root password: 123456 url: jdbc:mysql://localhost:3306/mybati ...

  10. JS(简单数据类型、数据类型转换)

    一. 数据类型简介 1.1 为什么需要数据类型 在计算机中,不同的数据所需占用的存储空间是不同的,为了便于把数据分成所需内存大小不同的数据,充分利用存储空间,于是定义了不同的数据类型.简单来说,数据类 ...