做者最近遇到了一個有趣的問題,咱們都知道文件讀取有兩種類型javascript
fs.readFileSync(); //同步讀取
fs.readFile(); //異步讀取
複製代碼
而Promise 是異步編程的一種解決方案, 那麼咱們可否封裝一個Promise版本的 readFile呢?css
咱們來看看阮一峯老師關於javascript是單線程的解釋html
連接:www.ruanyifeng.com/blog/2014/1…java
JavaScript語言的一大特色就是單線程,也就是說,同一個時間只能作一件事,在發出一個調用時,必須等待上一個任務執行完才能執行下一個任務,這種執行模式叫作同步。單線程就意味着,全部任務須要排隊,前一個任務結束,纔會執行後一個任務。若是前一個任務耗時很長,後一個任務就不得不一直等着。JavaScript語言的設計者意識到,這時主線程徹底能夠無論IO設備,掛起處於等待中的任務,先運行排在後面的任務。等到IO設備返回告終果,再回過頭,把掛起的任務繼續執行下去。因而,全部任務能夠分紅兩種,一種是同步任務,另外一種是異步任務。編程
所謂同步編程,就是計算機按順序一行一行依次執行代碼,當前代碼任務耗時執行會阻塞後續代碼的執行。promise
所謂異步編程,就是在調用在發出後,這個調用就直接返回了,調用者不會當即獲得結果,可是不會阻塞,能夠繼續執行後續的操做。用一句話來講就是併發
程序無須按照代碼順序自上而下的執行app
這是咱們要引入的template.html文件koa
<html>
<head></head>
<link rel="stylesheet" href="style.css">
<body>
<h1>不吃算拉~</h1>
<img src="./eat.jpg" alt="" width="100px" height="100px">
<script src="./common.js"></script>
</body>
</html>
複製代碼
樣式和js能夠本身寫,我寫的有點粗糙,在本地上預覽效果以下:異步
如今咱們用同步的方式讀取這個文件
const Koa = require('koa');
const app = new Koa();
const static = require('koa-static');
const fs = require('fs');
const main = ctx => {
ctx.response.type = 'html'; // 響應頭
const html = fs.readFileSync('./template.html','utf-8'); // 同步讀取
// console.log(html);
ctx.response.body =html;
}
app.use(static('./'));
app.use(main);
app.listen(3000);
複製代碼
這是同步的寫法,會形成阻塞。對於高併發來講,很是消耗時間。
如今咱們來使用性能更高,速度更快,並且沒有阻塞的異步方法。 代碼以下:
const Koa = require('koa');
const app = new Koa();
const static = require('koa-static');
const fs = require('fs');
const main = async ctx => {
ctx.response.type = 'html'; // 響應頭
// 封裝Promise 版本的 readFile
let pReadFile = function (filePath) {
return new Promise(function (resolve, reject) {
fs.readFile(filePath, 'utf-8', function (err, data) {
if (err) {
reject(err);
}
resolve(data);
});
})
}
await pReadFile('./template.html').then(data => {
ctx.response.body = data;
})
}
app.use(static('./'));
app.use(main); // 啓用了一個服務 給訪問者用 Visitors 使用
app.listen(3000);
複製代碼
預覽效果
能夠看到,咱們成功完成了readFile中Promise版本的封裝。對於以上代碼,其實咱們還有更簡單的方法來實現,這裏用到了流(Stream)的思想
const fs = require('fs');
const Koa = require('koa');
const app = new Koa();
const static = require('koa-static');
const main = ctx =>{
ctx.response.type = 'html';
ctx.response.body = fs.createReadStream('./template.html');
}
app.use(static('./'));
app.use(main);
app.listen(3000,function(){
console.log('在3000端口上啓動成功')
});
複製代碼
能夠看到, 流的使用更增強大。這裏不作過多贅述。
筆者目前仍是一名在讀大三學生, 若是有相應錯誤,歡迎大佬指正,也歡迎你們可以一塊兒交流問題,但願能和你們一塊兒獲得成長!