node-event-fs-stream-router-async事件event模块

node-event-fs-stream-router-async事件event模块

使用事件:EventEmitter 事件的参数 只执行一个的事件监听器

Node.js核心API的大部分是围绕一个惯用的异步事件驱动架构构建的,其中某些类型的对象(称为“发射器”)周期性地发出命名事件,导致调用Function对象(“侦听器”)

const EventEmmiter = require('events')

class myEmmiter extends EventEmmiter {}

const evt = new myEmmiter()

// evt.on('play', function (name) {
// console.log(name)
// })

const callback = (name) => {
console.log(name)
}

evt.on('play', callback)

// evt.removeListener('play', callback)

evt.emit('play', '结爱')
evt.emit('play', '黄皮子坟')

1.fs文件基本操作
1.1 简介:
Node.js 的 fs 是一个类似标准 POSIX 函数的用来操作文件的模块,它对所有的文件系统操作都有异步 和同步两种形式。不过,需要注意的是“当采用异步形式的时候,回调函数的第一个参数都会保留给异常,如果 操作成功完成,则第一个参数会是 null 或 undefined”

1.2.fs 模块引入及基本用法:

    const fs = require('fs');
    //异步的方式
    fs.readFile('./test.js', (err, data) => {//handle })
    const data = fs.readFileSync('./test.js'); //同步的方式

1.3.fs.open(path, flags[, mode], callback) 异步的方式打开文件

fs.open 方法通常用来打开一个文件地址、URL 或者 Buffer。
其中 flags 参数可以是:
r - 以读取模式打开文件。如果文件不存在则发生异常。
r+ - 以读写模式打开文件。如果文件不存在则发生异常。
rs+ - 以同步读写模式打开文件。命令操作系统绕过本地文件系统缓存。
使用:

		 const fs = require('fs');
        fs.open('./public/test.js', 'rs+', (err, fd) => {        
        if(err) { console.log('文件打开失败!'); return false;
          }
        fs.write(fd, ...) //在这里可以对上述打开的文件进行一系列的操作 })

1.4如果您想采用同步的方式来操作,则应该使用 fs.openSync()。

const fs = require('fs');
const fd = fs.openSync('./public/test.js', 'rs+');

1.5 fs.readFile(path[, options], callback) 异步的方式读取文件

fs.readFile 方法可以用来读取一个文件的具体内容

const fs = require('fs');
fs.readFile('./test.js', 'utf-8', (err, data) => { if (err) throw err; console.log(data);//这里将输出test.js的具体内容
})

注意:

如果您需要使用同步的方式来读取文件,可以使用 fs.readFileSync 方法来实现。
由于 fs 模块对每一 个文件操作都提供了同步和异步两种操作方式,
这里以及下文都将只演示异步的方式(因为,方法的实现就差 一个回调函数)。

1.6 fs.write(fd, buffer[, offset[, length[, position]]], callback) 异步的方式写入文件

通过 fs.write 方法可以将字符串或者 Buffer 写入一个指定的文件(fd)

const fs = require('fs');
fs.open('./test.txt', 'rs+', (err, fd) => {
    if(err) {
console.log('文件打开失败!');
        return false;
    }
    fs.write(fd, 'hello world', (err, written, str) => {
        if(err) throw err;
        console.log(written); //11
        console.log(str); //hello world
}) })

1.7 fs.close(fd, callback) 异步的方式关闭文件
与 fs.open 方法相反,fs.close 方法可以用来关闭一个已经打开的文件。例如:

const fs = require('fs');
fs.open('./public/test.js', 'rs+', (err, fd) => {
    if (err) {
console.log('文件打开失败!');
        return false;
    }
//handle
fs.close(fd, err => {
    if (err) throw err; //关闭文件的回调函数体
}) })

1.8 fs.unlink(path, callback) 异步的方式删除文件 fs.unlink 方法可以删除一个文件(不能删除目录)。例如:

const fs = require('fs');
fs.unlink('./test.txt', err => { if (err) throw err; console.log('删除成功!');
})

1.9 fs.readdir(path[, options], callback) 读取一个目录
当我们需要知道某个目录下都有那些文件或者文件夹的时候,我们可以使用 fs.readdir 方法来实现。例 如:

const fs = require('fs');
fs.readdir('./', (err, files) => {
    if (err) throw err;
    console.log(files.join(';')); //这里将输出当前路径下的所有文件、文件夹名称并通过“;”分隔 
})

注意: fs 模块的每一个方法都提供了异步与同步的两种操作方式。其中,异步的方式性能高,是一种推 荐的操作方式。如果您需要采用同步的方式,只要在异步方法名后面加上 Sync 即可,同时去掉末尾的 callback 参数。
1.10 http模块创建服务器+fs文件操作+服务器监听

const http = require('http')
const fs = require('fs')

http.createServer((req, res) => {
    res.writeHead(200, {
        'content-type': 'text/html'
    })

switch (req.url) {
    case '/home':
        fs.readFile('./views/home.html', 'utf8', (err, data) => {
            res.end(data)
        })
        break;
    case '/api/signin':
        res.end('signin')
        break;
    case '/app.js':
        fs.readFile('./app.js', 'utf8', (err, data) => {
            res.end(data)
        })
        break;
    case '/ajax-loader.gif':
        fs.readFile('./ajax-loader.gif', (err, data) => {
            res.end(data)
        })
        break;
    default:
        res.end('404')
 }
}).listen(8000, 'localhost', () => {
    console.log('server is running at localhost:8000');
})

2.stream流模块

2.1 fs流的简介
2.1.1 stream:流是一个抽象接口,有四种流类型:

readable:可读
writable:可写操作
duplex:可读可写操作
transform:操作被写入数据,然后读出结果

2.1.2 所有的stream 象都是EventEmitter 的 例,常用事件有:

data:当有数据可读触发
end:没有数据可读触发
error:发生错误时触发
finish:完成触发
2.2 fs.createReadStream(path[, options]) 创建一个可读流 fs.createReadStream 方法通常用来创建一个可读流。例如:

const fs = require('fs');
var data = '';
// 创建可读流
var readerStream = fs.createReadStream('./public/test.js');
// 设置编码为 utf8。 readerStream.setEncoding('UTF8');
// 处理流事件 --> data, end, and error readerStream.on('data', function(chunk) {
    data += chunk;
});
readerStream.on('end',function(){
    console.log(data);
});
readerStream.on('error', function(err){
    console.log(err.stack);
}); console.log("程序执行完毕");

2.3 fs.createWriteStream(path[, options]) 创建一个可写流
fs.createWriteStream 方法可以创建一个可写入流对象,通过这个对象可以将自己想要写入的信息写到指定文件。例如:

var fs = require("fs");
var data = '这是我要写入到test.js文件中的数据';
// 创建一个可以写入的流,写入到文件 output.txt 中
var writerStream = fs.createWriteStream('./public/test.js');
// 使用 utf8 编码写入数据 writerStream.write(data, 'UTF8');
// 标记文件末尾 writerStream.end();
// 处理流事件 --> data, end, and error writerStream.on('finish', function () {
console.log("写入完成。"); });
writerStream.on('error', function (err) {
    console.log(err.stack);
}); console.log("程序执行完毕");

2.4 readerStream.pipe(writerStream) 将可读流信息导入可写流(即管道流) readerStream.pipe 方法可以将我们创建的可读流文件信息一一导入到可写流当中。例如:

var fs = require("fs");
// 创建一个可读流
var readerStream = fs.createReadStream('input.txt');
// 创建一个可写流
var writerStream = fs.createWriteStream('output.txt');
// 管道读写操作
// 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中 readerStream.pipe(writerStream); console.log("程序执行完毕");

2.5 链式流

链式是通过连接输出流到另外一个流并创建多个流操作链的机制。链式流一般用于管道操作。例如我们可 以用管道和链式来压缩和解压文件:

//压缩
var fs = require("fs");
var zlib = require('zlib');
// 压缩 input.txt 文件为 input.txt.gz 
fs.createReadStream('input.txt')
    .pipe(zlib.createGzip())
.pipe(fs.createWriteStream('input.txt.gz')); console.log("文件压缩完成。");
//解压
var fs = require("fs");
var zlib = require('zlib');
// 解压 input.txt.gz 文件为 input.txt fs.createReadStream('input.txt.gz')
    .pipe(zlib.createGunzip())
.pipe(fs.createWriteStream('input.txt')); console.log("文件解压完成。");

3.路由+图片读取

总结:
1. 为什么要引进前端路由这样一个东西
2. 书写路由
3. js文件的读取
4. 图片的读取
5.css文件的读取

const http = require('http')
const fs = require('fs')

http.createServer((req, res) => {
    res.writeHead(200, {
    'content-type': 'text/html'
})

switch (req.url) {
    case '/home':
        fs.readFile('./views/home.html', 'utf8', (err, data) => {
            res.end(data)
        })
        break;
    case '/api/signin':
        res.end('signin')
        break;
    case '/app.js':
        fs.readFile('./app.js', 'utf8', (err, data) => {
            res.end(data)
        })
        break;
    case '/ajax-loader.gif’://图片读取
        fs.readFile('./ajax-loader.gif', (err, data) => {
            res.end(data)
        })
        break;


//如果你的图片和当前js不在同一级目录,这个时候我们必须去遍历目录,然后找到你要发送的那一个,然后再去读取文件,然后发送

case ‘/bd_logo1.png’:

fs.readdir('./views',(err,data) => {
    console.log( data ) ;

    data.forEach( (item,index) => {
        if(item == 'bd_logo1.png'){
                fs.readFile(item,(err,data)=>{
                    res.end(data)
                })
        }
    })
})
break;
    default:
        res.end('404')
    }
}).listen(8000, 'localhost', () => {
console.log('server is running at localhost:8000');
})

4.异步流程相关(async)

  1. Promise
    https://blog.csdn.net/MrJavaweb/article/details/79475949

  2. Generator
    https://www.cnblogs.com/imwtr/p/5913294.html

  3. Async-await

  4. Node.js 中的nextTick()和setimmediate()
    https://www.cnblogs.com/5ishare/p/5268273.html

5.async库
https://caolan.github.io/async/

参考文档
Event-loop
http://www.ruanyifeng.com/blog/2014/10/event-loop.html?bsh_bid=983729729
史上最易读懂的 Promise/A+ 完全实现
https://zhuanlan.zhihu.com/p/21834559

4.1 promise

const p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('p1 resolved!')
    }, 1000)
})
.then((result) => {
    console.log(result);
})

const p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('p2 resolved!')
    }, 2000)
})
.then((result) => {
    console.log(result);
})

// Promise.all([p1, p2])
// .then(() => {
    // console.log('done.');
// })

Promise.race([p1, p2])
.then(() => {
    console.log('done.');
})

4.2 generator

function* fibonacci() {
    let [prev, curr] = [0, 1];
    for (;;) {
        yield curr;
        [prev, curr] = [curr, prev + curr];
    }
}

for (let n of fibonacci()) {
    if (n > 1000) break;
    console.log(n);
}
4.3 async-await

const foo = function () {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('done.')
        }, 1000)
    })
}

const async = async () => {
    console.log(await foo());
}

async()

4.4 nextTick()和setImmediate()

process.nextTick(function(){
    console.log("nextTick延迟执行A");
});
process.nextTick(function(){
    console.log("nextTick延迟执行B");
setImmediate(function(){
    console.log("setImmediate延迟执行C");
});
process.nextTick(function(){
    console.log("nextTick延迟执行D");
});
});
setImmediate(function(){
    console.log("setImmediate延迟执行E");
process.nextTick(function(){
    console.log("强势插入F");
});
setImmediate(function(){
    console.log("setImmediate延迟执行G");
});
});
setImmediate(function(){
    console.log("setImmediate延迟执行H");
process.nextTick(function(){
    console.log("强势插入I");
});
process.nextTick(function(){
    console.log("强势插入J");
});
setImmediate(function(){
    console.log("setImmediate延迟执行K");
});
});
console.log("正常执行L");

4.5 async
串行无关联

async.series({
one: function(callback) {
    setTimeout(function() {
    callback(null, 1);
}, 200);
},
two: function(callback){
    setTimeout(function() {
    callback(null, 2);
}, 100);
}
}, function(err, results) {
    console.log(results);
    console.timeEnd('flag')
});
console.time('flag')
并行无关联


async.parallel({
one: function(callback) {
    setTimeout(function() {
        callback(null, 1);
    }, 200);
},
two: function(callback){
    setTimeout(function() {
        callback(null, 2);
    }, 100);
}
}, function(err, results) {
    console.log(results);
    console.timeEnd('flag')
});
串行有关联

async.waterfall([
    function(callback) {
        request.get('http://api.douban.com/v2/movie/in_theaters', (err, response, body) => {
            if (!err) {
                callback(null, JSON.parse(body));
            } else {
                console.log(err);
            }
        })
},
function(arg1, callback) {
    let movies = arg1.subjects.map((value) => value.title)
    let query = querystring.escape(`${movies[0]}`)
    request.get(`http://api.douban.com/v2/movie/search?q=${query}`, (err, response, body) => {
        if (!err) {
            // console.log(JSON.parse(body));
            callback(null, JSON.parse(body), 'three');
        } else {
            console.log(err);
        }
    })

},
function(arg1, arg2, callback) {
    console.log(arg1);
    callback(null, [arg1, arg2]);
}
], function (err, result) {
    console.log(result);
    console.timeEnd('flag')
});
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值