做者最近遇到了一个有趣的问题,咱们都知道文件读取有两种类型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);
复制代码
预览效果
对于以上代码,其实咱们还有更简单的方法来实现,这里用到了流(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端口上启动成功')
});
复制代码
能够看到, 流的使用更增强大。这里不作过多赘述。
笔者目前仍是一名在读大三学生, 若是有相应错误,欢迎大佬指正,也欢迎你们可以一块儿交流问题,但愿能和你们一块儿获得成长!