.vb.net 执行js方法_Deno的执行机制
上一篇主要圍繞Deno核心模塊中安全沙箱機(jī)制與依賴引入管理進(jìn)行了講解。本篇文章我們將對Deno的執(zhí)行機(jī)制進(jìn)行一些介紹。
Deno的架構(gòu)
先說說Deno的架構(gòu)吧,這是官網(wǎng)的核心架構(gòu)圖
不過這張圖很久沒更新了,有些實(shí)現(xiàn)有些變化。主要變化就是libdeno已經(jīng)替換成rusty_v8,js可以直接和rust進(jìn)行交互了,使用rust就可以完成功能開發(fā)。
Deno里面js與rust的交互都會通過Deno.core.send和Deno.core.recv這兩個方法,send發(fā)起同步任務(wù),recv用來觸發(fā)異步回調(diào)。
Tokio
Tokio是一個事件驅(qū)動的非阻塞I/O平臺,用于使用Rust編程語言編寫異步應(yīng)用程序,相當(dāng)于node中l(wèi)ibuv。Tokio中的異步模型,是基于future實(shí)現(xiàn)的,熟悉Rust語言的應(yīng)該很了解。基于我們熟悉的promise,簡單對比一下,future的基本特征:
future特征:trait SimpleFuture { type Output; fn poll(&mut self, wake: fn()) -> Poll<Self::Output>;} enum Poll { Ready(T), Pending,}js中的promise狀態(tài)轉(zhuǎn)移靠的是push,它本身就是一個事件源,能夠主動去改變自身狀態(tài),我們在then函數(shù)中注冊的回調(diào),會自動在下一個微任務(wù)隊列中執(zhí)行;
而future靠的是poll,需要一個excutor去輪詢獲取其狀態(tài),也就是說excutor會在適當(dāng)?shù)臅r候執(zhí)行future的poll方法,當(dāng)返回狀態(tài)為Poll::Pending也就意味需要excutor等待進(jìn)行下一次輪詢,當(dāng)返回Poll::Ready也就是意味future已經(jīng)完成,然后根據(jù)返回的值去判斷是否出錯,去執(zhí)行下一步代碼邏輯。
當(dāng)然了,excutor不會不間斷地去輪詢,所以future的poll方法里面是可以設(shè)置一個waker(喚醒任務(wù)),去通知excutor什么時候該來輪詢的。
Deno程序是怎么執(zhí)行的
入口函數(shù):cli/main.rs的main方法,主要干了兩件事:
解析命令行參數(shù)然后創(chuàng)建對應(yīng)的future(任務(wù))
啟動Tokio執(zhí)行future(任務(wù))
通過代碼可以看出,關(guān)鍵的步驟就是Run對應(yīng)的邏輯,也就是run_command方法。
核心邏輯就是Deno會創(chuàng)建一個MainWorker,就是我們的主進(jìn)程,然后是四個關(guān)鍵步驟:執(zhí)行用戶邏輯代碼->觸發(fā)load事件->事件循環(huán)->觸發(fā)unload事件
JS與Rust交互
代碼路徑:core/core.js
deno里面JS與Rust的交互只能通過send和recv這兩個方法
send會根據(jù)opId去調(diào)用對應(yīng)的rust方法,同步方法會直接返回,異步的話,需要通過recv去獲取異步結(jié)果
Object.assign(window.Deno.core, { jsonOpAsync, jsonOpSync, setAsyncHandler,dispatch: send, ops, close,sharedQueue: {}, ... })其中ops很關(guān)鍵,它是一個系統(tǒng)操作映射表,將操作和一個唯一的id進(jìn)行關(guān)聯(lián),是JS和Rust之間溝通的橋梁。
整個core.js就是給Window.Deno.core定義這些api方法,Deno中觸發(fā)任務(wù)的代碼如下:
//同步Deno.core.dispatch(opId, scratchBytes, ...zeroCopy);//異步Deno.core.setAsyncHandler(opId,cb)Deno.core.dispatch(opId, scratchBytes, ...zeroCopy);接下來,我們通過關(guān)鍵代碼,看下基本流程是什么樣的。
通過setAsyncHandler設(shè)定的回調(diào)函數(shù),會進(jìn)行初始化,回調(diào)函數(shù)會存儲到全局的handles表里。初始化函數(shù)里設(shè)置recv的回調(diào)函數(shù),供Tokio異步任務(wù)完成后觸發(fā)。handleAsyncMsgFromRust函數(shù)則會從全局的回調(diào)隊列中取出隊首任務(wù),根據(jù)opId去執(zhí)行對應(yīng)的handler。
核心代碼實(shí)現(xiàn):
最后來到core/bingding.rs的initialize_context,在這里是deno初始化核心方法的地方(都是掛在Deno.core這個對象下),send和recv也是在這里注入到JS中的。
用一張流程圖,將上述的片段串一下:
總結(jié)
本期我們主要講了deno的部分實(shí)現(xiàn)與執(zhí)行機(jī)制,之后的文章我們會在deno的生態(tài)及工程化等方面繼續(xù)進(jìn)行講解,敬請期待。
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的.vb.net 执行js方法_Deno的执行机制的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 分块的单点修改查询区间和_模版 单点修
- 下一篇: 项目实体类报错_第一次开发项目感想