當咱們以同步的方式編寫耗時的代碼,那麼就會阻塞JS的單線程,形成CPU一直等待IO完成纔去執行後面的代碼。javascript
而CPU的執行速度是遠遠大於硬盤IO速度的,這樣等待只會形成資源的浪費。java
異步IO就是爲了解決這個問題的,異步能儘量不讓CPU閒着,它不會在那等着IO完成;而是傳遞給底層的事件循環一個函數,本身去執行下面的代碼。等磁盤IO完成後,函數就會被執行來做爲通知。node
雖然異步和回調的編程方式能充分利用CPU,可是當代碼邏輯變的愈來愈複雜後,新的問題出現了——Callback hell回調地域!git
實現以下功能:程序員
- 判斷一個文件是文件仍是目錄;
- 若是是目錄,讀取這個目錄下的文件,找出結尾是txt的文件;
- 獲取這些txt文件大小。
function withoutPromise() {
let target = "test";
fs.stat(target, (err, stat)=>{
if(err){
throw err;
}
// 若是是文件夾
if(stat.isDirectory()){
fs.readdir(target, (err, files)=>{
// 遍歷files
files.forEach( f =>{
if(path.extname(f) === '.txt'){
fs.stat(path.join(target, f), (err, stat)=>{
console.log(f+ " : "+stat.size);
});
}
} );
});
}
});
}
async function withPromise() {
let target = "test";
//將fs.stat轉爲一個能夠返回Promise對象的方法
let pstat = util.promisify(fs.stat);
let stat = await pstat(target);
// 若是是文件夾
if(stat.isDirectory()){
//將fs.readdir轉爲一個能夠返回Promise對象的方法
let preaddir = util.promisify(fs.readdir)
let files = await preaddir(target)
files.forEach( async (f) => {
if(path.extname(f) === '.txt'){
let stat = await pstat(path.join(target, f));
console.log(stat.size);
}
});
}
}
Promise
和async/await
即是爲了解決Callback hell的問題。github
promise
的做用是對異步回調代碼包裝一下,把原來的一個回調函數拆成2個回調函數,這樣的好處是可讀性更好。語法以下:編程
// 建立promise對象
let promise = new Promise((resolve, reject)=>{
// 在異步操做成功的狀況選調用resolve,失敗的時候調用reject
fs.readFile('xxx.txt',(err, data)=>{
if(err){
reject(err)
}else {
resolve(data.toString())
}
})
});
// 使用promise
promise.then((text)=>{
//then方法是當Promise內部調用了resolve的時候執行
}).catch((err)=>{
//catch方法是當Promise內部調用了reject的時候執行
console.log(err);
})
async/await
的做用是直接將Promise異步代碼變爲同步的寫法,注意,代碼仍然是異步的。promise
語法要求:異步
await
只能用在async
修飾的方法中,可是有async
不要求必定有await
。await
後面只能跟async
方法和promise
。假設擁有了一個promise對象,如今使用async/await能夠這樣寫:async
async function asyncDemo() {
try {
// 當promise的then方法執行的時候
let text = await promise
// 當你用promise包裝了全部的異步回調代碼後,就能夠一直await,真正意義實現了以同步的方式寫異步代碼
console.log('異步道明執行');
}catch (e){
// 捕獲到promise的catch方法的異常
console.log(e);
}
}
asyncDemo()
console.log('我是同步代碼');
promise
包裝異步回調代碼,可以使用node提供的util.promisify
方法;async/await
編寫異步代碼。黑馬程序員 120天全棧區塊鏈開發 開源教程
https://github.com/itheima1/BlockChain
一番同步了對應的學習視頻到B站,長按識別可訪問一番B站主頁觀看。