成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

有趣的 Async hooks 模塊

開發(fā) 前端
在 Node.js 中,上下文傳遞一直是一個非常困難的問題,Node.js 通過 AsyncLocalStorage 提供了一種解決方案,今天看到一個庫中實現(xiàn)了類似 AsyncLocalStorage 的能力,還挺有意思的。

在 Node.js 中,Async hooks 是一個非常有意思且強大的模塊(雖然性能上存在一些問題),在 APM 中,我們可以借助這個模塊做很多事情。本文介紹兩個有趣的用法。

AsyncLocalStorage

在 Node.js 中,上下文傳遞一直是一個非常困難的問題,Node.js 通過 AsyncLocalStorage 提供了一種解決方案,今天看到一個庫中實現(xiàn)了類似 AsyncLocalStorage 的能力,還挺有意思的。代碼如下。

class ALS {
    constructor() {
        this._contexts = new Map();
        this._stack = [];
        this.hook = createHook({
            init: this._init.bind(this),
            before: this._before.bind(this),
            after: this._after.bind(this),
            destroy: this._destroy.bind(this),
        });
    }

    context() {
        return this._stack[this._stack.length - 1];
    }

    run(context, fn, thisArg, ...args) {
        this._enterContext(context);
        try {
            return fn.call(thisArg, ...args);
        }
        finally {
            this._exitContext();
        }
    }

    enable() {
        this.hook.enable();
    }

    disable() {
        this.hook.disable();
        this._contexts.clear();
        this._stack = [];
    }

    _init(asyncId) {
        const context = this._stack[this._stack.length - 1];
        if (context !== undefined) {
            this._contexts.set(asyncId, context);
        }
    }

    _destroy(asyncId) {
        this._contexts.delete(asyncId);
    }

    _before(asyncId) {
        const context = this._contexts.get(asyncId);
        this._enterContext(context);
    }

    _after() {
        this._exitContext();
    }

    _enterContext(context) {
        this._stack.push(context);
    }

    _exitContext() {
        this._stack.pop();
    }
}

這個方式是基于 Async hooks 實現(xiàn)的,原理是在 init 鉤子中獲取當前的上下文,然后把當前的上下文傳遞到當前創(chuàng)建的異步資源的,接著在執(zhí)行異步資源回調前,Node.js 會執(zhí)行 before 鉤子,before 鉤子中會把當前異步資源(正在執(zhí)行回調的這個資源)的上下文壓入棧中,然后在回調里就可以通過 context 函數(shù)獲取到當前的上下文,實際上獲取的就是剛才壓入棧中的內容,執(zhí)行完回調后再出棧。前面介紹了其工作原理,主要是實現(xiàn)異步資源的上下文傳遞且在執(zhí)行回調時通過棧的方式實現(xiàn)了上下文的管理,那么第一個上下文是如何來的呢?答案是通過 run 函數(shù)(Node.js 中還可以通過 enterWith),run 會把用戶設置的上下文壓入棧中,然后執(zhí)行了一個用戶傳入的函數(shù),如果這個函數(shù)中創(chuàng)建了異步資源,那么用戶傳入的上下文就會傳遞到這個新創(chuàng)建的異步資源中,后面執(zhí)行這個異步資源的回調時,就可以拿到對應的上下文了。接著看一下使用效果。

const als = new ALS();
als.enable();

http.createServer((req, res) => {
    als.run(req, () => {
        setImmediate(() => {
            console.log(als.context().url);
            res.end();
        });
    })
}).listen(9999, () => {
    http.get({ port: 9999, host: '127.0.0.1' });
});

執(zhí)行上面代碼會輸出 /。可以看到在 setImmediate 的回調中(setImmediate 會創(chuàng)建一個異步資源)成功拿到了 run 時設置的上下文。

監(jiān)控異步回調的耗時

在 Node.js 中,代碼執(zhí)行耗時是一個非常值得關注的地方,Node.js 也提供了很多手段采集代碼執(zhí)行的耗時信息,下面介紹的是基于 Async hooks 實現(xiàn)的回調函數(shù)耗時監(jiān)控。

const { createHook } = require('async_hooks');
const fs = require('fs');

const map = {};

createHook({
    init: (asyncId) => {
        map[asyncId] = { stack: new Error().stack };
    },
    before: (asyncId) => {
        if (map[asyncId]) {
            map[asyncId].start = Date.now();
        }
    },
    after: (asyncId) => {
        if (map[asyncId]) {
            fs.writeFileSync(1, `callback cost: ${Date.now() - map[asyncId].start}, stack: ${map[asyncId].stack}`);
        }
    },
    destroy: (asyncId) => {
        delete map[asyncId];
    }
}).enable();

setTimeout(() => {
    for (let i = 0; i < 1000000000; i++) {

    }
});

實現(xiàn)原理非常簡單,主要是利用 before 和 after 鉤子實現(xiàn)了回調的耗時統(tǒng)計,就不多介紹,社區(qū)中也有同學實現(xiàn)了這個能力,具體可以參考 https://github.com/naugtur/blocked-at/tree/master。


責任編輯:武曉燕 來源: 編程雜技
相關推薦

2021-01-26 08:07:44

Node.js模塊 Async

2021-08-12 01:00:29

NodejsAsync

2021-05-21 06:13:35

React Hooks react-refrReact

2023-11-06 08:00:00

ReactJavaScript開發(fā)

2020-10-28 09:12:48

React架構Hooks

2021-01-27 08:05:55

本地存儲HTTP

2019-08-20 15:16:26

Reacthooks前端

2014-09-19 11:17:48

面試題

2010-07-17 01:03:13

CMD Telnet

2022-03-31 17:54:29

ReactHooks前端

2020-09-19 17:46:20

React Hooks開發(fā)函數(shù)

2023-03-13 08:47:06

CSS數(shù)學函數(shù)

2016-10-21 10:15:53

2014-07-15 10:31:07

asyncawait

2016-11-22 11:08:34

asyncjavascript

2025-03-06 03:00:00

hook??復數(shù)函數(shù)

2021-03-18 08:00:55

組件Hooks React

2024-11-07 12:47:51

hook函數(shù)git

2022-08-21 09:41:42

ReactVue3前端

2022-04-16 20:10:00

React Hookfiber框架
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 99爱在线 | 国内成人免费视频 | 极品的亚洲 | 一区二区国产精品 | 天天色综| 欧美性精品 | 欧美成人a∨高清免费观看 老司机午夜性大片 | 精品国产18久久久久久二百 | 99精品一区二区 | 亚洲成人日韩 | 亚洲精色 | 51ⅴ精品国产91久久久久久 | 自拍偷拍3p | 伊人色综合久久久天天蜜桃 | 高清人人天天夜夜曰狠狠狠狠 | 国产精品日日做人人爱 | 亚洲免费影院 | 国产999精品久久久久久 | 成人三级网址 | 欧美激情一区二区 | 成人av激情 | 91福利网址 | 一级日韩 | 国产精品久久久久久久久久久免费看 | 三级黄色片在线观看 | 日韩精品视频一区二区三区 | 九色porny自拍视频 | 一级黄色播放 | 国产精品7777777 | 一区在线观看 | 91色综合 | 日本人麻豆 | 国产精品伦理一区二区三区 | 欧美日韩综合一区 | 小h片免费观看久久久久 | 欧美男人天堂 | 国产做a爱免费视频 | 国产高清视频一区 | 久久精品99国产精品 | 国产成人精品免费视频大全最热 | 成人小视频在线观看 |