ArkTS語言基礎(chǔ)類庫是HarmonyOS系統(tǒng)上為應(yīng)用開發(fā)者提供的常用基礎(chǔ)能力,主要包含能力如下圖所示。
圖1 ArkTS語言基礎(chǔ)類庫能力示意圖

-
提供異步并發(fā)和多線程并發(fā)的能力。
- 支持Promise和async/await等標(biāo)準(zhǔn)的JS異步并發(fā)能力。
- TaskPool為應(yīng)用程序提供一個多線程的運(yùn)行環(huán)境,降低整體資源的消耗、提高系統(tǒng)的整體性能,開發(fā)者無需關(guān)心線程實例的生命周期。
- Worker支持多線程并發(fā),支持Worker線程和宿主線程之間進(jìn)行通信,開發(fā)者需要主動創(chuàng)建和關(guān)閉Worker線程。
提供常見的容器類庫增、刪、改、查的能力。
-
提供XML、URL、URI構(gòu)造和解析的能力。
- XML被設(shè)計用來傳輸和存儲數(shù)據(jù),是一種可擴(kuò)展標(biāo)記語言。語言基礎(chǔ)類庫提供了XML生成、解析與轉(zhuǎn)換的能力。
- URL、URI構(gòu)造和解析能力:其中URI是統(tǒng)一資源標(biāo)識符,可以唯一標(biāo)識一個資源。URL為統(tǒng)一資源定位符,可以提供找到該資源的路徑。
-
提供常見的字符串和二進(jìn)制數(shù)據(jù)處理的能力,以及控制臺打印的相關(guān)能力。
- 字符串編解碼功能。
- 基于Base64的字節(jié)編碼和解碼功能。
- 提供常見的有理數(shù)操作支持,包括有理數(shù)的比較、獲取分子分母等功能。
- 提供Scope接口用于描述一個字段的有效范圍。
- 提供二進(jìn)制數(shù)據(jù)處理的能力,常見于TCP流或文件系統(tǒng)操作等場景中用于處理二進(jìn)制數(shù)據(jù)流。
- Console提供控制臺打印的能力。
并發(fā)
Promise和async/await提供異步并發(fā)能力,是標(biāo)準(zhǔn)的JS異步語法。異步代碼會被掛起并在之后繼續(xù)執(zhí)行,同一時間只有一段代碼執(zhí)行,適用于單次I/O任務(wù)的場景開發(fā),例如一次網(wǎng)絡(luò)請求、一次文件讀寫等操作。
異步語法是一種編程語言的特性,允許程序在執(zhí)行某些操作時不必等待其完成,而是可以繼續(xù)執(zhí)行其他操作。
Promise
Promise是一種用于處理異步操作的對象,可以將異步操作轉(zhuǎn)換為類似于同步操作的風(fēng)格,以方便代碼編寫和維護(hù)。Promise提供了一個狀態(tài)機(jī)制來管理異步操作的不同階段,并提供了一些方法來注冊回調(diào)函數(shù)以處理異步操作的成功或失敗的結(jié)果。
Promise有三種狀態(tài):pending(進(jìn)行中)、fulfilled(已完成)和rejected(已拒絕)。Promise對象創(chuàng)建后處于pending狀態(tài),并在異步操作完成后轉(zhuǎn)換為fulfilled或rejected狀態(tài)。
最基本的用法是通過構(gòu)造函數(shù)實例化一個Promise對象,同時傳入一個帶有兩個參數(shù)的函數(shù),通常稱為executor函數(shù)。executor函數(shù)接收兩個參數(shù):resolve和reject,分別表示異步操作成功和失敗時的回調(diào)函數(shù)。例如,以下代碼創(chuàng)建了一個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函數(shù)模擬了一個異步操作,并在1秒鐘后隨機(jī)生成一個數(shù)字。如果隨機(jī)數(shù)大于0.5,則執(zhí)行resolve回調(diào)函數(shù)并將隨機(jī)數(shù)作為參數(shù)傳遞;否則執(zhí)行reject回調(diào)函數(shù)并傳遞一個錯誤對象作為參數(shù)。
Promise對象創(chuàng)建后,可以使用then方法和catch方法指定fulfilled狀態(tài)和rejected狀態(tài)的回調(diào)函數(shù)。then方法可接受兩個參數(shù),一個處理fulfilled狀態(tài)的函數(shù),另一個處理rejected狀態(tài)的函數(shù)。只傳一個參數(shù)則表示狀態(tài)改變就執(zhí)行,不區(qū)分狀態(tài)結(jié)果。使用catch方法注冊一個回調(diào)函數(shù),用于處理“失敗”的結(jié)果,即捕獲Promise的狀態(tài)改變?yōu)閞ejected狀態(tài)或操作失敗拋出的異常。例如:
promise.then(result => {
console.info(`Random number is ${result}`);
}).catch(error => {
console.error(error.message);
});
上述代碼中,then方法的回調(diào)函數(shù)接收Promise對象的成功結(jié)果作為參數(shù),并將其輸出到控制臺上。如果Promise對象進(jìn)入rejected狀態(tài),則catch方法的回調(diào)函數(shù)接收錯誤對象作為參數(shù),并將其輸出到控制臺上。
async/await
async/await是一種用于處理異步操作的Promise語法糖,使得編寫異步代碼變得更加簡單和易讀。通過使用async關(guān)鍵字聲明一個函數(shù)為異步函數(shù),并使用await關(guān)鍵字等待Promise的解析(完成或拒絕),以同步的方式編寫異步操作的代碼。
async函數(shù)是一個返回Promise對象的函數(shù),用于表示一個異步操作。在async函數(shù)內(nèi)部,可以使用await關(guān)鍵字等待一個Promise對象的解析,并返回其解析值。如果一個async函數(shù)拋出異常,那么該函數(shù)返回的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關(guān)鍵字來等待Promise對象的解析,并將其解析值存儲在result變量中。
需要注意的是,由于要等待異步操作完成,因此需要將整個操作包在async函數(shù)中。除了在async函數(shù)中使用await外,還可以使用try/catch塊來捕獲異步操作中的異常。
async function myAsyncFunction() {
try {
const result = await new Promise((resolve) => {
resolve('Hello, world!');
});
} catch (e) {
console.error(`Get exception: ${e}`);
}
}
myAsyncFunction();
Promise和async/await提供異步并發(fā)能力,適用于單次I/O任務(wù)的場景開發(fā),本文以使用異步進(jìn)行單次文件寫入為例來提供指導(dǎo)。
實現(xiàn)單次I/O任務(wù)邏輯。
import fs from '@ohos.file.fs';
import common from '@ohos.app.ability.common';
async function write(data: string, file: fs.File): Promise<void> {
fs.write(file.fd, data).then((writeLen: number) => {
console.info('write data length is: ' + writeLen)
}).catch((err) => {
console.error(`Failed to write data. Code is ${err.code}, message is ${err.message}`);
})
}
采用異步能力調(diào)用單次I/O任務(wù)。示例中的filePath的獲取方式請參見獲取應(yīng)用文件路徑。
async function testFunc(): Promise<void> {
let context = getContext() as common.UIAbilityContext;
let filePath: string = context.filesDir + "/test.txt"; // 應(yīng)用文件路徑
let file: fs.File = await fs.open(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
write('Hello World!', file).then(() => {
console.info('Succeeded in writing data.');
}).catch((err) => {
console.error(`Failed to write data. Code is ${err.code}, message is ${err.message}`);
})
fs.close(file);
}
testFunc();