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

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

回調(diào)

NodeJS 最大的賣點——事件機制和異步 IO,對開發(fā)者并不是透明的。開發(fā)者需要按異步方式編寫代碼才用得上這個賣點,而這一點也遭到了一些 NodeJS 反對者的抨擊。但不管怎樣,異步編程確實是 NodeJS 最大的特點,沒有掌握異步編程就不能說是真正學(xué)會了 NodeJS。本章將介紹與異步編程相關(guān)的各種知識。

在代碼中,異步編程的直接體現(xiàn)就是回調(diào)。異步編程依托于回調(diào)來實現(xiàn),但不能說使用了回調(diào)后程序就異步化了。我們首先可以看看以下代碼。

function heavyCompute(n, callback) {
    var count = 0,
        i, j;

    for (i = n; i > 0; --i) {
        for (j = n; j > 0; --j) {
            count += 1;
        }
    }

    callback(count);
}

heavyCompute(10000, function (count) {
    console.log(count);
});

console.log('hello');

-- Console ------------------------------
100000000
hello

可以看到,以上代碼中的回調(diào)函數(shù)仍然先于后續(xù)代碼執(zhí)行。JS 本身是單線程運行的,不可能在一段代碼還未結(jié)束運行時去運行別的代碼,因此也就不存在異步執(zhí)行的概念。

但是,如果某個函數(shù)做的事情是創(chuàng)建一個別的線程或進程,并與JS主線程并行地做一些事情,并在事情做完后通知 JS 主線程,那情況又不一樣了。我們接著看看以下代碼。

setTimeout(function () {
    console.log('world');
}, 1000);

console.log('hello');

-- Console ------------------------------
hello
world

這次可以看到,回調(diào)函數(shù)后于后續(xù)代碼執(zhí)行了。如同上邊所說,JS 本身是單線程的,無法異步執(zhí)行,因此我們可以認為 setTimeout 這類 JS 規(guī)范之外的由運行環(huán)境提供的特殊函數(shù)做的事情是創(chuàng)建一個平行線程后立即返回,讓 JS 主進程可以接著執(zhí)行后續(xù)代碼,并在收到平行進程的通知后再執(zhí)行回調(diào)函數(shù)。除了 setTimeout、setInterval 這些常見的,這類函數(shù)還包括 NodeJS 提供的諸如 fs.readFile 之類的異步 API。

另外,我們?nèi)匀换氐?JS 是單線程運行的這個事實上,這決定了 JS 在執(zhí)行完一段代碼之前無法執(zhí)行包括回調(diào)函數(shù)在內(nèi)的別的代碼。也就是說,即使平行線程完成工作了,通知 JS 主線程執(zhí)行回調(diào)函數(shù)了,回調(diào)函數(shù)也要等到 JS 主線程空閑時才能開始執(zhí)行。以下就是這么一個例子。

function heavyCompute(n) {
    var count = 0,
        i, j;

    for (i = n; i > 0; --i) {
        for (j = n; j > 0; --j) {
            count += 1;
        }
    }
}

var t = new Date();

setTimeout(function () {
    console.log(new Date() - t);
}, 1000);

heavyCompute(50000);

-- Console ------------------------------
8520

可以看到,本來應(yīng)該在1秒后被調(diào)用的回調(diào)函數(shù)因為 JS 主線程忙于運行其它代碼,實際執(zhí)行時間被大幅延遲。