最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解使用抽象語法樹AST實現(xiàn)一個AOP切面邏輯

 更新時間:2023年04月06日 17:03:19   作者:頭疼腦脹的代碼搬運工  
這篇文章主要為大家介紹了使用抽象語法樹AST實現(xiàn)一個AOP切面邏輯的簡單方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

開篇

AST 功能很靈活,可以通過改變一些自定義結構便可以輸入自定義的功能,下面簡單的展示下如何利用抽象語法樹AST實現(xiàn)一個AOP切面邏輯

一、實現(xiàn)目的

js 文件下的全部方法添加一個開始事件和一個結束事件并傳入方法名,以便監(jiān)聽某個方法的調用。

1、work.js

function eat(){
    let food = "apple"
    let time = '2小時'
    return '吃' + food + '用時' + time
}
function work(){
}
console.log(eat())

控制臺打印

可以看到,輸入了執(zhí)行 eat 方法的開始事件及結束事件。其實,這個過程就是 work.js 轉成語法樹后,對方法節(jié)點進行了處理,添加了兩個切面方法:startend 事件。

2、aop.js

這個文件用來聲明 startend 事件。

function start(funcName){
    console.log('開始執(zhí)行:' + funcName + '方法')
}
function end(funcName){
    console.log('執(zhí)行結束:' + funcName + '方法')
}

二、利用語法樹添加切面事件

//文件操作工具
const fs = require('fs');
//JS代碼轉語法樹工具
const parser = require('./babel-core/node_modules/babylon');
//語法樹遍歷工具
const traverse = require('./babel-core/node_modules/babel-traverse');
//語法樹轉JS代碼工具
const generator = require('./babel-core/node_modules/babel-generator');
//聲明語法樹類型工具
const t = require('./babel-core/node_modules/babel-types');
//獲取aop代碼
let aop = fs.readFileSync('./aop.js','utf-8')
//獲取需要添加切面的代碼
let content = fs.readFileSync('./work.js','utf-8')
//將需要添加切面的代碼轉換為語法樹
let ast = parser.parse(content,{
    sourceType:'script'
})
//遍歷指定語法樹時操作項(這里遍歷的指定節(jié)點是FunctionDeclaration方法)
const visitor = {
    FunctionDeclaration:({ node }) => {
        //獲取每個方法體里面的節(jié)點
        let funcBody = node.body.body
        //創(chuàng)建一個名為start,參數為當前方法名的執(zhí)行節(jié)點,后面的參數為創(chuàng)建一個名為start方法的參數
        let start = t.callExpression(t.identifier('start'), [t.identifier(`"${node.id.name}"`)])
        //添加到方法的最前面
        funcBody.unshift(start)
        //判斷最后一個節(jié)點是不是return,方式結束事件調用節(jié)點在最后無法調用。
        let lastNode = funcBody.slice(-1)
        //創(chuàng)建一個名為end,參數為當前方法名的執(zhí)行節(jié)點,后面的參數為end方法的參數
        let end = t.callExpression(t.identifier('end'), [t.identifier(`"${node.id.name}"`)])
        //設定end節(jié)點添加的位置
        let insertEndEventPosition = (funcBody.length)
        if(lastNode[0].type == 'ReturnStatement'){
            //放在return節(jié)點的前面
            insertEndEventPosition -= 1
        }
        //添加end節(jié)點
        funcBody.splice(insertEndEventPosition,0,end)
    }
}
//開始遍歷操作語法樹
traverse.default(ast,visitor)
//將處理完的語法樹再次轉換為JS代碼
let codeResult = generator.default(ast)
//這里需要添加aop里面的兩個切面事件到最終的JS代碼里。
let outFileCode = aop + '\n\n' + codeResult.code
// 寫入文件操作
fs.mkdir('cache',(err)=>{
    if(!err){
        fs.writeFile('cache/main.js',outFileCode,(err)=>{
            if(!err){
                console.log('文件創(chuàng)建完成')
            }
        })
    }
})

上面的代碼執(zhí)行完后,看下 main.js 生成的代碼內容。

function start(funcName){
    console.log('開始執(zhí)行:' + funcName + '方法')
}
function end(funcName){
    console.log('執(zhí)行結束:' + funcName + '方法')
}
function eat() {
    start("eat")
    let food = "apple";
    let time = '2小時';
    end("eat")
    return '吃' + food + '用時' + time;
}
function work() {
    start("work")
    end("work")
}
console.log(eat());

相比較之前的 work.js 文件,添加了兩個切面方法的同時,保證每個方法都添加了 startend 事件。這樣再調用的時候便可直接在執(zhí)行前后操作其他任務了。

三、總結與思考

其實上面的操作人工也可以直接操作,但是,將一切重復單一的工作交給程序,這或許是代碼存在的真正意義。一個簡單的例子或許能打開一個新的世界,雖然,每一行代碼都是獨一無二的,但是如果追本溯源,最初并且真切的思想卻是相通的

以上就是詳解使用抽象語法樹AST實現(xiàn)一個AOP切面邏輯的詳細內容,更多關于AST抽象語法樹實現(xiàn)AOP的資料請關注腳本之家其它相關文章!

相關文章

  • 一文詳解如何在IDEA中配置Node.js

    一文詳解如何在IDEA中配置Node.js

    idea中支持運行很多種編程語言,只需要在電腦中安裝好對應的語言環(huán)境,下面這篇文章主要給大家介紹了關于如何在IDEA中配置Node.js的相關資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-02-02
  • Node.js進程管理之進程集群詳解

    Node.js進程管理之進程集群詳解

    這篇文章介紹了Node.js進程管理之進程集群,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • node版本快速切換及管理方法

    node版本快速切換及管理方法

    這篇文章主要為大家介紹了node版本快速切換及管理方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • package-lock.json解決依賴的版本管理使用詳解

    package-lock.json解決依賴的版本管理使用詳解

    這篇文章主要為大家介紹了package-lock.json解決依賴的版本管理使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-08-08
  • 如何使用Node寫靜態(tài)文件服務器

    如何使用Node寫靜態(tài)文件服務器

    這篇文章主要介紹了如何使用Node寫靜態(tài)文件服務器,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,感興趣的小伙伴可以參考一下
    2022-09-09
  • Elasticsearch插件及nodejs的安裝配置

    Elasticsearch插件及nodejs的安裝配置

    這篇文章主要為大家介紹了Elasticsearch插件及nodejs的安裝配置,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-04-04
  • 使用Node.js搭建Web服務器

    使用Node.js搭建Web服務器

    這篇文章介紹了使用Node.js搭建Web服務器的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • 前端node Session和JWT鑒權登錄示例詳解

    前端node Session和JWT鑒權登錄示例詳解

    關于前端鑒權登錄是比較常見的需求了,本文將從服務端渲染和前后端分離的不同角度下演示鑒權,為大家介紹前端node Session和JWT鑒權登錄示例詳解
    2022-07-07
  • Koa2框架快速入門與基本使用方式

    Koa2框架快速入門與基本使用方式

    這篇文章主要介紹了Koa2框架快速入門與基本使用方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • nodejs多版本管理總結

    nodejs多版本管理總結

    這篇文章主要介紹了nodejs多版本管理的相關知識點,以及實際操作方法和代碼,有需要的朋友參考下。
    2018-04-04

最新評論

巨野县| 营口市| 铜陵市| 三亚市| 翁牛特旗| 乌鲁木齐县| 广水市| 久治县| 长葛市| 隆安县| 大竹县| 石河子市| 乌拉特中旗| 垦利县| 新津县| 诸城市| 巴塘县| 增城市| 大港区| 丘北县| 德钦县| 彭山县| 潍坊市| 龙南县| 浦江县| 辽阳县| 玉溪市| 隆子县| 遂平县| 长兴县| 额尔古纳市| 定兴县| 蒲城县| 银川市| 萝北县| 鹤庆县| 喀喇沁旗| 剑阁县| 德惠市| 龙门县| 东海县|