deno學(xué)習(xí)(2)---從Hello World開始

deno的執(zhí)行非常簡(jiǎn)單,使用deno xx.ts即可淤井。 從deno hello.ts出發(fā)哄酝,探究一下deno的運(yùn)行機(jī)制。

  • 學(xué)習(xí)目標(biāo)
    1. deno代碼的模塊
    2. 各模塊之間的交互模式

回顧

  • 在上一節(jié)學(xué)習(xí)過程中瘟裸,已經(jīng)知道了執(zhí)行make指令之后,會(huì)將go代碼诵竭、ts代碼话告、js代碼已經(jīng)node_module代碼打包÷盐浚可以大致猜測(cè)一下沙郭,在整個(gè)deno項(xiàng)目里面,go會(huì)占一部分裳朋,js也會(huì)占一部分病线。作為js和go的交互模塊,v8worker也是很重要的一部分鲤嫡。

v8worker

  • v8worker本身是ry大神基于V8做的一個(gè)go和js調(diào)用的中間層送挑。主體只有兩個(gè)功能:
    1. 接收消息
    • golang接收來自js的消息
//worker.go
func New(cb ReceiveMessageCallback) *Worker {
    //...
}
  • js接收來自golang的消息
V8Worker2.recv((ab: ArrayBuffer) => {
//...
}
  1. 發(fā)送消息給js
  • golang分送消息到j(luò)s
//worker.go
func (w *Worker) SendBytes(msg []byte) error {
  • js分送消息到golang
V8Worker2.send(msg)

在deno里面,作者對(duì)v8worker做了簡(jiǎn)單的封裝暖眼,在go和js層面分別做了一個(gè) 分發(fā)器惕耕。dispatch.godispatch.ts,分別提供了訂閱诫肠、發(fā)布功能司澎。

dispatch.go

func Sub(channel string, cb Subscriber) {
    subscribers, ok := channels[channel]
    subscribers = append(subscribers, cb)
    channels[channel] = subscribers
}

func Pub(channel string, payload []byte) {
    wg.Add(1)
    resChan <- &BaseMsg{
        Channel: channel,
        Payload: payload,
    }
}

dispatch.js

export function sub(channel: string, cb: MessageCallback): void {
  let subscribers = channels.get(channel);
  subscribers.push(cb);
}

export function pub(channel: string, payload: Uint8Array): null | ArrayBuffer {
  const msg = pb.BaseMsg.fromObject({ channel, payload });
// ...
  return send(ab);
}

通過以上代碼欺缘,就可以實(shí)現(xiàn)一個(gè)訂閱者模式,從而實(shí)現(xiàn)數(shù)據(jù)交互挤安。值得一提的是谚殊,數(shù)據(jù)交互格式為protobuf。這種方式相當(dāng)安全蛤铜、高效嫩絮。

main.go

  • 通過下面代碼可以知道,deno的主入口就是 ./cmd/main.go文件
deno: msg.pb.go $(GO_FILES)
   go build -o deno ./cmd
  • ./cmd/main.go
package main

import (
    "github.com/ry/deno"
)
func main() {
    //初始化deno配置昂羡,預(yù)加載js代碼絮记。形成bridger
    deno.Init()

    //執(zhí)行denoMain()方法
    deno.Eval("deno_main.js", "denoMain()")
    deno.Loop()
}
  1. 初始化 2. 執(zhí)行js 里面的 denoMain方法 3.執(zhí)行一個(gè)輪詢
  • main.go./cmd/main.go引用了 deno包虐先。Init怨愤、Eval、Loop都位于main.go

  • Init

    //創(chuàng)建所需文件夾 在 ${home}/.deno   創(chuàng)建 src cache 兩個(gè)文件夾
    createDirs()
    //訂閱 os
    InitOS()
    //訂閱echox
    InitEcho()
    //訂閱timers
    InitTimers()
    //訂閱fetch
    InitFetch()


    //一個(gè)v8工作線程
    worker = v8worker2.New(recv)

    //加載main.js代碼.
    //main.js就是Makefile里面通過
    /**
    #生成 dist/main.js 通過 ts文件 和 node_moduels
dist/main.js: $(TS_FILES) node_modules
    ./node_modules/.bin/tsc --noEmit # Only for type checking.
    ./node_modules/.bin/parcel build --out-dir=dist/ --log-level=1 --no-minify main.ts
        打包生成的代碼蛹批。
    */
    main_js = stringAsset("main.js")
    //加載main.js
    err := worker.Load("/main.js", main_js)
    exitOnError(err)
    //代碼的map撰洗,用于定位代碼.
    main_map = stringAsset("main.map")
  • Eval
    // It's up to library users to call
// deno.Eval("deno_main.js", "denoMain()")
func Eval(filename string, code string) {
    //執(zhí)行代碼
    err := worker.Load(filename, code)
    exitOnError(err)
}
  • Loop

func Loop() {
    cwd, err := os.Getwd()
    check(err)
    /**
        可以將v8worker2 理解為一個(gè)C/S的架構(gòu)。
        Client發(fā)送消息腐芍,Server端回復(fù)消息差导。
    */
    PubMsg("start", &Msg{
        Command:        Msg_START,
        StartCwd:       cwd,
        StartArgv:      workerArgs,
        StartDebugFlag: *flagDebug,
        StartMainJs:    main_js,
        StartMainMap:   main_map,
    })
    DispatchLoop()
}

執(zhí)行流程

  1. 初始化。
    • 下面四個(gè)方法猪勇,通過V8注冊(cè)方法设褐,實(shí)現(xiàn)對(duì)js調(diào)用的訂閱。
    InitOS()
    //訂閱echox
    InitEcho()
    //訂閱timers
    InitTimers()
    //訂閱fetch
    InitFetch()

os.go

//訂閱了os泣刹。提供了5種模式助析。
Sub("os", func(buf []byte) []byte {
        switch msg.Command {
        case Msg_CODE_FETCH:
        case Msg_CODE_CACHE:
        case Msg_EXIT:  
        case Msg_READ_FILE_SYNC:
                //讀取文件      
        case Msg_WRITE_FILE_SYNC:   
        }
    })

剩下三個(gè)大同小異,不做具體說明椅您。

  - 加載 js文件
//會(huì)加載 /dist/main.js 文件
main_js = stringAsset("main.js")
//加載main.js外冀,編譯并執(zhí)行。
err := worker.Load("/main.js", main_js)
  1. 執(zhí)行denoMain方法掀泳。
  • denoMain方法是 位于main.js 里面雪隧。實(shí)際上在打包之前,是位于main.ts下员舵。
(window as any)["denoMain"] = () => {
  initTimers(); //初始化timer
  initFetch(); //初始化fetch 

//訂閱start事件脑沿。
  dispatch.sub("start", (payload: Uint8Array) => {
    runtime.setup(mainJs, mainMap);
//就是文件路徑
    const inputFn = argv[0];
//模塊加載
    const mod = runtime.resolveModule(inputFn, `${cwd}/`);
//執(zhí)行編譯和運(yùn)行ts代碼
    mod.compileAndRun();
  });

這里訂閱了start事件,等待觸發(fā)马僻。觸發(fā)的時(shí)候捅伤,就是對(duì)ts文件做編譯、執(zhí)行的時(shí)候巫玻。

  1. 開始Loop
    main.go
func Loop() {
    cwd, err := os.Getwd()
    /**
      觸發(fā)start事件丛忆。
    */
    PubMsg("start", &Msg{
        Command:        Msg_START,
        StartCwd:       cwd,
        StartArgv:      workerArgs,
        StartDebugFlag: *flagDebug,
        StartMainJs:    main_js,
        StartMainMap:   main_map,
    })
        //對(duì)消息輪詢,實(shí)現(xiàn)數(shù)據(jù)交換仍秤。
    DispatchLoop()
}

dispatch.go

func DispatchLoop() {
      // 對(duì)協(xié)程做監(jiān)控熄诡。
    //實(shí)際上,Pub會(huì)新建一個(gè)協(xié)程消息诗力,這里做監(jiān)聽凰浮。有新信息就通過worker發(fā)送給js層。
    for {
        select {
        case msg := <-resChan:
            out, err := proto.Marshal(msg)
            err = worker.SendBytes(out)
        case <-doneChan:
            return
        }
}
image.png

總結(jié)

  • 目前來看deno是一個(gè)很簡(jiǎn)單的執(zhí)行ts的程序苇本。效率也不是很高袜茧。實(shí)際上對(duì)ts的解析和執(zhí)行都是在runtime時(shí)期運(yùn)行的,相對(duì)于以前對(duì)typescript先編譯成js再使用的方式瓣窄,是一種全新的嘗試笛厦。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市俺夕,隨后出現(xiàn)的幾起案子裳凸,更是在濱河造成了極大的恐慌,老刑警劉巖劝贸,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件姨谷,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡映九,警方通過查閱死者的電腦和手機(jī)梦湘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來件甥,“玉大人捌议,你說我怎么就攤上這事〗朗矗” “怎么了禁灼?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)轿曙。 經(jīng)常有香客問我弄捕,道長(zhǎng),這世上最難降的妖魔是什么导帝? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任守谓,我火速辦了婚禮,結(jié)果婚禮上您单,老公的妹妹穿的比我還像新娘斋荞。我一直安慰自己,他們只是感情好虐秦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布平酿。 她就那樣靜靜地躺著凤优,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蜈彼。 梳的紋絲不亂的頭發(fā)上筑辨,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音幸逆,去河邊找鬼棍辕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛还绘,可吹牛的內(nèi)容都是我干的楚昭。 我是一名探鬼主播,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼拍顷,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼抚太!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起菇怀,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤凭舶,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后爱沟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帅霜,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年呼伸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了身冀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡括享,死狀恐怖搂根,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情铃辖,我是刑警寧澤剩愧,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站娇斩,受9級(jí)特大地震影響仁卷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜犬第,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一锦积、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧歉嗓,春花似錦丰介、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)带膀。三九已至,卻和暖如春橙垢,著一層夾襖步出監(jiān)牢的瞬間本砰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工钢悲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人舔株。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓莺琳,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親载慈。 傳聞我的和親對(duì)象是個(gè)殘疾皇子惭等,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 29,338評(píng)論 8 265
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,092評(píng)論 1 32
  • 1. 分布式系統(tǒng)核心問題 參考書籍:《區(qū)塊鏈原理、設(shè)計(jì)與應(yīng)用》 一致性問題例子:兩個(gè)不同的電影院買同一種電影票办铡,如...
    molscar閱讀 907評(píng)論 0 0
  • 如果你要問妹迷們:為什么喜歡好妹妹?答案有很多童叠,總結(jié)起來有幾個(gè)關(guān)鍵因素: 1.接地氣的小清新民謠配上“無(wú)節(jié)操”的逗...
    了了君閱讀 7,078評(píng)論 13 60
  • 你是風(fēng)雨 我卻把你當(dāng)彩虹 你是夜空 我卻把你當(dāng)霓虹 數(shù)不清的星子 睡不醒的夢(mèng) 你說我傻 把星子當(dāng)珍寶 把夢(mèng)境當(dāng)人生
    一泡日照閱讀 191評(píng)論 4 3