在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

單線程也能開發異步任務?ACE JS框架到底是如何做到的

話說科技 ? 2021-08-13 17:16 ? 次閱讀

HarmonyOS 2提供了兩種應用開發語言:Java和JS。Java線程特性能夠讓多任務并行,充分利用硬件資源開發出高性能的應用。而JS卻是一個單線程語言,無法像Java一樣創建新的Thread,用JS語言開發是否會導致硬件資源無法充分利用的情況呢?

本文給大家介紹“ACE JS的單線程異步機制”就是解決這個問題的。然而,說到 “單線程”與“異步”,大家可能會比較疑惑,因為單線程和異步在概念上是沖突的,單線程無法做到多任務并發,也就不會存在異步這種通信機制。

確實,JS語言本身是無法實現異步的,但是ACE JS框架卻提供了多線程的宿主環境,通過消息通信機制讓JS語言有了異步的屬性,下面我們來詳細描述其原理。

ACE開發框架

使用JS開發HarmonyOS應用,使用的開發框架名為ACE(Ability Cross-Platform Environment),該框架適用于手機、平板、智慧屏、智慧表、車機等設備,具備“一次開發,多端部署”的能力。

ACE框架包括應用層(Application)、前端框架層(Framework)、引擎層(Engine)和平臺適配層(Porting Layer),如下圖所示:

pYYBAGEWOIyATdaWAADtwa2aYQQ444.png

●Application

應用層表示開發者使用JS UI框架開發的FA應用,這里的FA應用特指JS FA應用。

●Framework

前端框架層主要完成前端頁面解析,以及提供MVVM(Model-View-ViewModel)開發模式、頁面路由機制和自定義組件等能力。

●Engine

引擎層主要提供動畫解析、DOM(Document Object Model)樹構建、布局計算、渲染命令構建與繪制、事件管理等能力。

●Porting Layer

適配層主要完成對平臺層進行抽象,提供抽象接口,可以對接到系統平臺。比如:事件對接、渲染管線對接和系統生命周期對接等。

ACE開發框架的線程模型

poYBAGEWOI2Ae7o0AAD6WYLdZrY885.png

每個HarmonyOS JS應用,都是通過上圖所示的ACE開發框架進行加載渲染的。ACE開發框架包含了JS線程、UI線程、GPU線程、IO線程,并且在ACE框架外還會存在一類后臺任務線程。

其中GPU線程與IO線程主要是ACE框架初始化與頁面加載渲染的過程需要的,為ACE框架內部的專有線程,不會被應用直接操作到,應用不需要特別關注;UI線程、JS線程和后臺任務線程會與應用開發代碼相關,后面著重分析這三個線程的作用和關系。

●UI線程:負責應用界面的繪制刷新,與應用的進程號相同,又叫主線程。如果開發JS+JAVA的混合編程,JAVA PA(Particle Ability)的onStart/onConnect等Ability生命周期回調便是運行在主線程,若在這些生命周期回調上執行耗時操作則會導致JS UI的繪制刷新卡住。

●JS線程:應用的JS代碼會被JS引擎解析執行,并運行在JS線程上,而JS又是單線程語言,所以目前我們工程中看到的所有的JS代碼都會執行在這個進程下唯一的JS線程上。

●后臺任務線程:這里是對ACE框架外部的后臺線程的一個統稱,并不單指一個線程,也并不唯一。后臺任務線程包含了Java PA線程、文件操作API、網絡訪問API內部實現等相關線程。

下面我們結合測試代碼來看一下這3個線程之間的關系。

JS線程與UI線程的關系

為了驗證JS線程與UI線程的關系,我們準備了一個實驗性質的Demo,主要代碼以及運行過程的Log如下:

首先我們在IDE建立一個Empty Ablity(JS)模板的HelloWorld工程,在生命周期、按鈕響應回調方法里增加Log以觀察線程情況。剛創建的app.js中Application生命周期默認已經有Log,無需額外添加。

我們只需要在主界面index.js文件中onInit增加日志:

console.info('page.default onInit');

然后在index.hml中增加一個button以及會一直進行動畫的progress組件:

I'm a button

最后在index.js中增加按鈕點擊響應事件以及Log,并且嘗試sleep阻塞js線程:

function sleep(delay) {

for (var t = Date.now(); Date.now() - t <= delay; );

}

onButtonClick() {

console.info('onButtonClick begin');

sleep(1000);

console.info('onButtonClick end');

}

將應用運行起來,點擊兩次按鈕,得到如下Log:

poYBAGEWOI2AHLLyAAC_IDf7wvk861.png

從輸出的Log中,我們可以看到這個JS FA進程號為22592,也就是說UI線程是22592;生命周期回調以及按鈕響應均在24077線程,這個就是JS線程,所以JS線程與UI線程不是同一個線程。

并且我們嘗試通過sleep方法阻塞JS線程,想觀察JS線程阻塞是否會影響到UI線程的刷新。最終得出的結論是無論JS線程sleep多長時間,UI界面上的progress組件動畫一直會不斷刷新,按鈕也會有按壓效果變化,所以我們可以推測JS線程與UI線程的相互調用應該是通過某種消息機制完成的,而不是阻塞式的調用。

JS線程與后臺任務線程的關系

ACE JS框架提供了JS FA(Feature Ability)調用Java PA(Particle Ability)的機制,該機制提供了一種通道來傳遞方法調用、處理數據返回以及訂閱事件上報。我們同樣制作一個Demo來驗證JS線程與Java PA線程的關系:

在JS中,我們通過FeatureAbility.callAbility拉起并調用了名為一個類名為ServiceAbility的Java PA,并拿到返回結果:

var action = {};

action.bundleName = 'com.blancwu.test';

action.abilityName = 'com.blancwu.test.ServiceAbility';

action.messageCode = 1001;

action.abilityType = 0;

action.syncOption = 0;

console.info('FeatureAbility.callAbility begin' + JSON.stringify(action));FeatureAbility.callAbility(action).then(function (value) {

console.info('FeatureAbility.callAbility async result ' + JSON.stringify(value));

})

console.info('FeatureAbility.callAbilityend'+JSON.stringify(action));

在ServiceAbility的onRemoteRequest中增加Log輸出,并sleep 1秒鐘,以便觀察線程情況與之間關系:

@Override

public boolean onRemoteRequest(int code, MessageParcel data, MessageParcel reply, MessageOption option) throws RemoteException {

HiLog.info(LABEL_LOG, "onRemoteRequest begin " + code);

if (code == 1001) {

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

Map result = new HashMap();

result.put("result", 1);

reply.writeString(ZSONObject.toZSONString(result));

}

HiLog.info(LABEL_LOG, "onRemoteRequest end " + code);

return super.onRemoteRequest(code, data, reply, option);

}

以上代碼完成后,我們進行執行,得到的Log如下:

pYYBAGEWOI6AYZIJAAHEEAp7qeg938.png

我們觀察到本次運行主進程(UI線程)號為4133,JS代碼執行在JS線程5887,Java PA響應onRemoteRequest執行在另一個后臺任務線程5837。通過Log我們看到onRemoteRequst即使阻塞了后臺任務線程1s也不會影響JS線程的并行執行以及主線程(UI線程)上動畫的刷新,做到了JS線程與后臺任務線程異步地執行事務。

JS線程的異步機制

上面從代碼實驗角度觀察到了JS線程與其他線程的異步關系,那么JS線程是怎么處理來自其他多個線程的調用的呢?我們先來看一下傳統的瀏覽器環境下的機制:

pYYBAGEWOJGAV9OgAAN5QOfulTo678.png

上圖中,JS線程中的函數調用會存在于棧(stack)中,棧中的函數可以調用瀏覽器環境提供的WebAPIs,包含了DOM、ajax、timeout等API,這些API會在瀏覽器環境提供的另外一個外部線程執行,執行完成后會在任務隊列(callback queue)中加入對應的回調事件(如onClick、onLoad、onDone)。當棧中的代碼執行完畢,即棧清空后,JS線程又會通過event loop取出任務隊列中的下一個任務進行執行,以此類推完成整個的程序執行。更具體的機制可以去看阮一峰老師介紹JS EventLoop的文章:

●JS EventLoop介紹

http://www.ruanyifeng.com/blog/2014/10/event-loop.html

HarmonyOS ACE開發框架同樣遵循上述最基本的EventLoop調度機制,并且提供了更多的機制和API,讓業務邏輯可以在外部線程執行,包含了上面提到的Java PA以及異步回調的系統能力API。其中,異步回調的系統能力API包含如文件系統操作和網絡操作等,具體大家可以按照我們實驗Demo的方法去嘗試一下。

●參考

https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-apis-file-storage-0000000000629445

未來發展的展望

目前ACE JS應用內實現多線程的最佳方式是通過混合編程調用Java PA方式,但未來純JS應用一定會越來越多,那么,只支持單線程的JS ACE框架的異步API能解決各種復雜場景的問題嗎?

單線程的JS加上異步API能夠很好解決單個I/O阻塞的問題,但是如果遇到大量的I/O事件,比如批刪除大量文件,通過for循環發起了大量異步任務,也會降低執行效率,甚至阻塞其他異步任務的執行。并且如果要使用JS語言開發計算密集型的任務,也無法在唯一的JS線程上進行。

這時就需要一個真正的JS多線程處理機制了,雖然目前HarmonyOS 2還未支持,但未來HarmonyOS會考慮規劃出與HTML5類似提供支持WebWorker機制,支持開發出多線程的JS代碼,提供給應用開發者更多的發揮空間。

fqj

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 代碼
    +關注

    關注

    30

    文章

    4891

    瀏覽量

    70305
  • 單線程
    +關注

    關注

    0

    文章

    18

    瀏覽量

    1829
收藏 人收藏

    評論

    相關推薦
    熱點推薦

    LuatOS協程深度解析:小白能10分鐘學會,代碼效率直接起飛!

    嵌入式開發如何兼顧效率與簡潔?LuatOS協程給出完美答案!它用類線程的語法封裝異步邏輯,讓多任務開發
    的頭像 發表于 04-10 15:23 ?141次閱讀
    LuatOS協程深度解析:小白<b class='flag-5'>也</b>能10分鐘學會,代碼效率直接起飛!

    進程、線程、協程傻傻分不清?一文帶你徹底扒光它們的\"底褲\"!

    權(yield)實現協作,單線程內玩出多任務的感覺。 技術細節: 協程切換成本≈打哈欠(0.1μs~1μs) 阻塞操作會直接讓出CPU(比如等待網絡請求時,自動切換到其他協程) 必須依附于線程(就像
    發表于 03-26 09:27

    摩爾線程圖形顯卡MTT S80實現DeepSeek模型部署

    摩爾線程“全功能”圖形顯卡MTT S80,不僅游戲渲染性能強大,能玩《黑神話:悟空》,現在還能本地部署DeepSeek R1蒸餾模型。搭配最新發布的MUSA SDK RC3.1.1版本,開發者直接用開源框架Ollama就
    的頭像 發表于 02-21 15:46 ?1860次閱讀
    摩爾<b class='flag-5'>線程</b>圖形顯卡MTT S80實現DeepSeek模型部署

    藍牙AOA定位系統如何做到高精準度?

    藍牙AOA定位系統是一種高精度的室內定位技術,其高精準度是通過一系列高科技的技術和方法實現的。以下是給大家分析的幾點關于如何做到高精準度的幾個關鍵點:
    的頭像 發表于 12-13 11:42 ?546次閱讀

    ADC7846如何做到使用手指觸摸有效?

    ADC7846芯片觸摸轉換時候,不準,能否通過配置,如何做到使用手指觸摸有效?
    發表于 12-04 06:47

    工程行業中如何做到低碳甚至零碳

    低碳的生活方式越來越多地融入我們的日常習慣當中。但是在工程行業中如何做到低碳甚至零碳呢?
    的頭像 發表于 10-14 10:31 ?762次閱讀

    TPA3251如何做到180W的功率,電壓12V,電流應該多少?

    TPA3251如何做到180W的功率,電壓12V,電流應該多少,請推薦DCDC
    發表于 10-11 06:54

    鴻蒙跨端實踐-JS虛擬機架構實現

    類似的框架,我們需要自行實現以確保核心基礎能力的完整。 鴻蒙虛擬機的開發經歷了從最初 ArkTs2V8 到 JSVM + Roma新架構方案 。在此過程中,我們實現了完整的鴻蒙版的“J2V8”和 基于系統JSVM的JS虛擬機
    的頭像 發表于 09-30 14:42 ?2899次閱讀
    鴻蒙跨端實踐-<b class='flag-5'>JS</b>虛擬機架構實現

    寫 Verilog 如何做到心中有電路?

    問題(二) Q:如何通俗地講清 I2C、SPI、USB、UART、RS232 到底是什么東西?通俗,通俗,通俗。百度上的術語一大堆,到頭來把我繞的糊里糊涂,我知道您什么都懂,能解釋的讓外行人理解
    發表于 09-26 20:30

    js基礎之setTimeout與setInterval原理分析

    個定時器,讓函數在計時結束后再執行;后者則是每隔一定的時間,就啟動一次函數的執行。 從原理來看,兩者似乎并不復雜。但由于JavaScript引擎是單線程的,這就讓上述兩個定時器的實際執行變得稍微復雜了一些。下面我們來看一下兩者的運行機制與需要注意的問題。 基本原理 知識鋪墊 單線
    的頭像 發表于 09-19 15:10 ?1538次閱讀
    <b class='flag-5'>js</b>基礎之setTimeout與setInterval原理分析

    功放和運放到底是什么區別?

    想請問一下功放和運放到底是什么區別,感覺只要接一個小負載,運放的輸出電流可以很大啊?到底有什么區別啊
    發表于 09-10 07:00

    推薦一個支持js的嵌入式設備開發平臺

    可以通過vscode開發js,實時推送js代碼到設備里運行,無需編譯,支持屏幕,感興趣的可以看看 https://github.com/duoxianwulian/dxdop 提供很多js
    發表于 09-04 14:04

    運放的輸入電容到底是什么?

    我想請問一下運放的輸入電容到底是什么?
    發表于 09-04 06:52

    LMH6502的輸入電壓到底是多少?

    LMH6502的輸入電壓到底是多少,我稍微給如大一點點的信號,放大不行還能接受,我衰減都失真,
    發表于 08-27 07:02

    請問使用lwip創建socket,該如何做到非阻塞的接收發送數據?

    請問使用lwip創建socket,該如何做到非阻塞的接收發送數據?
    發表于 06-19 06:02
    主站蜘蛛池模板: 日日爱网址 | 亚洲欧美色视频 | 欧美一级乱理片免费观看 | 欧美婷婷色 | 久久国产精品免费 | 亚洲国产成+人+综合 | 久久精品久噜噜噜久久 | 欧美精品高清在线xxxx | h色小视频| 欧美极品xxxxⅹ另类 | 激情狠狠干 | 加勒比黑人喝羽月希奶水 | 天天射网| 男女交性视频免费视频 | 日本中文字幕在线播放 | 色www国产阿娇 | 国产成人精品亚洲 | 狠狠的操 | 亚洲人成毛片线播放 | 欧美色伊人 | 国产精品漂亮美女在线观看 | 欧美视频不卡一区二区三区 | 日韩第十页 | 午夜看片影院在线观看 | 奇米第四狠狠777高清秒播 | 久久伦子沙发 | 中文字幕一区二区三区四区五区人 | 五月天婷婷丁香中文在线观看 | 日韩三级中文 | 国产拍拍视频 | 在线黄网 | 日本特黄特色aaa大片免费欧 | 国产手机在线 | 欧美色图中文字幕 | 兔费看全黄三级 | 亚洲国产成人久久午夜 | 操白虎美女 | 每日最新avhd101天天看新片 | 天天狠天天插 | 亚欧美色| 77成人|