在代碼中,異步編程的直接體現(xiàn)就是回調(diào)。異步編程依托于回調(diào)來實(shí)現(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本身是單線程運(yùn)行的,不可能在一段代碼還未結(jié)束運(yùn)行時(shí)去運(yùn)行別的代碼,因此也就不存在異步執(zhí)行的概念。
但是,如果某個(gè)函數(shù)做的事情是創(chuàng)建一個(gè)別的線程或進(jìn)程,并與JS主線程并行地做一些事情,并在事情做完后通知JS主線程,那情況又不一樣了。我們接著看看以下代碼。
~~~
setTimeout(function () {
console.log('world');
}, 1000);
console.log('hello');
-- Console ------------------------------
hello
world
~~~
這次可以看到,回調(diào)函數(shù)后于后續(xù)代碼執(zhí)行了。如同上邊所說,JS本身是單線程的,無法異步執(zhí)行,因此我們可以認(rèn)為`setTimeout`這類JS規(guī)范之外的由運(yùn)行環(huán)境提供的特殊函數(shù)做的事情是創(chuàng)建一個(gè)平行線程后立即返回,讓JS主進(jìn)程可以接著執(zhí)行后續(xù)代碼,并在收到平行進(jìn)程的通知后再執(zhí)行回調(diào)函數(shù)。除了`setTimeout`、`setInterval`這些常見的,這類函數(shù)還包括NodeJS提供的諸如`fs.readFile`之類的異步API。
另外,我們?nèi)匀换氐絁S是單線程運(yùn)行的這個(gè)事實(shí)上,這決定了JS在執(zhí)行完一段代碼之前無法執(zhí)行包括回調(diào)函數(shù)在內(nèi)的別的代碼。也就是說,即使平行線程完成工作了,通知JS主線程執(zhí)行回調(diào)函數(shù)了,回調(diào)函數(shù)也要等到JS主線程空閑時(shí)才能開始執(zhí)行。以下就是這么一個(gè)例子。
~~~
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ù)因?yàn)镴S主線程忙于運(yùn)行其它代碼,實(shí)際執(zhí)行時(shí)間被大幅延遲。
- NodeJS基礎(chǔ)
- 什么是NodeJS
- 有啥用處
- 如何安裝
- 如何運(yùn)行
- 模塊
- 二進(jìn)制模塊
- 小結(jié)
- 代碼的組織和部署
- 模塊路徑解析規(guī)則
- 包(package)
- 命令行程序
- 工程目錄
- NPM
- 小結(jié)
- 文件操作
- 開門紅
- API走馬觀花
- 遍歷目錄
- 文本編碼
- 小結(jié)
- 網(wǎng)絡(luò)操作
- 開門紅
- API走馬觀花
- 靈機(jī)一點(diǎn)
- 小結(jié)
- 進(jìn)程管理
- 開門紅
- API走馬觀花
- 應(yīng)用場景
- 小結(jié)
- 異步編程
- 回調(diào)
- 代碼設(shè)計(jì)模式
- 域(Domain)
- 小結(jié)
- 大示例
- 需求
- 第一次迭代
- 第二次迭代
- 第三次迭代
- 第四次迭代
- 后續(xù)迭代
- 小結(jié)
