在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ HTML/ 域(Domain)
文本編碼
小結(jié)
API 走馬觀花
API 走馬觀花
迭代
小結(jié)
運行
回調(diào)
需求
代碼設(shè)計模式
進(jìn)程介紹
模塊
工程目錄
小結(jié)
小結(jié)
遍歷目錄
小結(jié)
小結(jié)
API 走馬觀花
用途
NPM
小結(jié)
安裝
網(wǎng)絡(luò)操作介紹
二進(jìn)制模塊
什么是 NodeJS
命令行程序
靈機(jī)一點
域(Domain)
應(yīng)用場景
模塊路徑解析規(guī)則
文件拷貝

域(Domain)

官方文檔: http://nodejs.org/api/domain.html

NodeJS 提供了 domain 模塊,可以簡化異步代碼的異常處理。在介紹該模塊之前,我們需要首先理解“域”的概念。簡單的講,一個域就是一個 JS 運行環(huán)境,在一個運行環(huán)境中,如果一個異常沒有被捕獲,將作為一個全局異常被拋出。NodeJS 通過 process 對象提供了捕獲全局異常的方法,示例代碼如下

process.on('uncaughtException', function (err) {
    console.log('Error: %s', err.message);
});

setTimeout(function (fn) {
    fn();
});

-- Console ------------------------------
Error: undefined is not a function

雖然全局異常有個地方可以捕獲了,但是對于大多數(shù)異常,我們希望盡早捕獲,并根據(jù)結(jié)果決定代碼的執(zhí)行路徑。我們用以下 HTTP 服務(wù)器代碼作為例子:

function async(request, callback) {
    // Do something.
    asyncA(request, function (err, data) {
        if (err) {
            callback(err);
        } else {
            // Do something
            asyncB(request, function (err, data) {
                if (err) {
                    callback(err);
                } else {
                    // Do something
                    asyncC(request, function (err, data) {
                        if (err) {
                            callback(err);
                        } else {
                            // Do something
                            callback(null, data);
                        }
                    });
                }
            });
        }
    });
}

http.createServer(function (request, response) {
    async(request, function (err, data) {
        if (err) {
            response.writeHead(500);
            response.end();
        } else {
            response.writeHead(200);
            response.end(data);
        }
    });
});

以上代碼將請求對象交給異步函數(shù)處理后,再根據(jù)處理結(jié)果返回響應(yīng)。這里采用了使用回調(diào)函數(shù)傳遞異常的方案,因此 async 函數(shù)內(nèi)部如果再多幾個異步函數(shù)調(diào)用的話,代碼就變成上邊這副鬼樣子了。為了讓代碼好看點,我們可以在每處理一個請求時,使用 domain 模塊創(chuàng)建一個子域(JS 子運行環(huán)境)。在子域內(nèi)運行的代碼可以隨意拋出異常,而這些異常可以通過子域?qū)ο蟮?error 事件統(tǒng)一捕獲。于是以上代碼可以做如下改造:

function async(request, callback) {
    // Do something.
    asyncA(request, function (data) {
        // Do something
        asyncB(request, function (data) {
            // Do something
            asyncC(request, function (data) {
                // Do something
                callback(data);
            });
        });
    });
}

http.createServer(function (request, response) {
    var d = domain.create();

    d.on('error', function () {
        response.writeHead(500);
        response.end();
    });

    d.run(function () {
        async(request, function (data) {
            response.writeHead(200);
            response.end(data);
        });
    });
});

可以看到,我們使用.create方法創(chuàng)建了一個子域?qū)ο?,并通過.run方法進(jìn)入需要在子域中運行的代碼的入口點。而位于子域中的異步函數(shù)回調(diào)函數(shù)由于不再需要捕獲異常,代碼一下子瘦身很多。

陷阱

無論是通過 process 對象的 uncaughtException 事件捕獲到全局異常,還是通過子域?qū)ο蟮?error 事件捕獲到了子域異常,在 NodeJS 官方文檔里都強(qiáng)烈建議處理完異常后立即重啟程序,而不是讓程序繼續(xù)運行。按照官方文檔的說法,發(fā)生異常后的程序處于一個不確定的運行狀態(tài),如果不立即退出的話,程序可能會發(fā)生嚴(yán)重內(nèi)存泄漏,也可能表現(xiàn)得很奇怪。

但這里需要澄清一些事實。JS 本身的throw..try..catch異常處理機(jī)制并不會導(dǎo)致內(nèi)存泄漏,也不會讓程序的執(zhí)行結(jié)果出乎意料,但 NodeJS 并不是存粹的 JS。NodeJS 里大量的 API 內(nèi)部是用 C/C++ 實現(xiàn)的,因此 NodeJS 程序的運行過程中,代碼執(zhí)行路徑穿梭于 JS 引擎內(nèi)部和外部,而 JS 的異常拋出機(jī)制可能會打斷正常的代碼執(zhí)行流程,導(dǎo)致 C/C++ 部分的代碼表現(xiàn)異常,進(jìn)而導(dǎo)致內(nèi)存泄漏等問題。

因此,使用 uncaughtException 或 domain 捕獲異常,代碼執(zhí)行路徑里涉及到了 C/C++ 部分的代碼時,如果不能確定是否會導(dǎo)致內(nèi)存泄漏等問題,最好在處理完異常后重啟程序比較妥當(dāng)。而使用 try 語句捕獲異常時一般捕獲到的都是 JS 本身的異常,不用擔(dān)心上訴問題。

上一篇:二進(jìn)制模塊下一篇:運行