开发桌面应用程序
开发服务器应用程序 => (1)微型站点,Node服务器要完成请求,响应,和数据库交互,各种业务逻辑。(2)node异步模式可以大量请求。node服务器不做任何与业务逻辑有关的事情。大部分只是简单的转发请求,可能会有一些额外的功能【简单的信息记录,静态资源托管。缓存】。
setTimeout/setInteval/setimmediate/console/_dirname(获取当前模块所在的目录)/_filename/Buffer(类型化数组,继承自Ulnt8Array)/process(cwd)/
①模块查找:
(1)绝度路径【不管啥路径最后都会被导成绝对路径】
require("D:\\a.js")
(2)相对路径
(3)后缀名:如果不提供后缀名,会自动补全
(4)文件名:如果提供该目录,不提供文件名,则自动寻找该目录中的index.js;
package.json中的main字段:表示包的默认入口,默认值index.js
②mudule
记录了当前模块的信息:被谁引用的又引用了哪些子模块。
③resolve:得到一个绝对路径
④this == exports == module.exports //true(this开始是指向exports的)
模块要么是commonjs 要么是es
①OS
os.EOL ->/r/n
os.arch() ->获取架构名(x32/x64)
os.cpus().length ->主频数(4)
os.freemem() ->获取当前剩余内存
os.homedir() ->获取用户目录
os.hostname() ->获取主机名
os.tmpdir() ->获取操作系统的临时目录
②path
const path = require("path")
const basename = path.basename("dd/ss/a.html")
console.log(basename) ->a.html
const basename = path.basename("dd/ss/a.html",'.html')
console.log(basename) ->a
console.log(path.sep) ->分隔符(\)
console.log(process.env.PATH.split(path.delimiter)) ->分割路径
const dir = path.dirname('ab/s/d.js');
console.log(dir) ->ab/s 获取目录
const path = require("path")
const ext = path.extname('ab/s/d.js');
console.log(ext) ->得到后缀名(.js)
const path = require("path")
const fullPath = path.join('a','b','c','d.js');
console.log(fullPath); ->a\b\c\d.js 拼接成完整路径
const path = require("path")
const rel = path.relative('/data/aaa','/data/bbb');
console.log(rel); ->换成相对路径 ..\bbb
const URL = require('url')
const url = new URL.URL("")
console.log(url)
③util工具包
const Util = require('util')
async function delay(duration = 1000){
return new Promise(resolve => {
setTimeout(() => {
resolve(duration)
}, duration);
});
}
const delayback = Util.callbackify(delay)
delayback(500,(err,d) => {
console.log(d) // ->500
})
//回调模式
function delayCallBack(duration,callback){
setTimeout(() => {
callback(null,duration)
},duration)
}
const delay = Util.promisify(delayCallBack);
delay(500).then(d => console.log(d))
//等同于
function delayCallBack(duration,callback){
setTimeout(() => {
callback(null,duration)
},duration)
}
// const delay = Util.promisify(delayCallBack);
// delay(500).then(d => console.log(d))
const delay = Util.promisify(delayCallBack);
(async () => {
const r = await delay(500);
console.log(r)
})();
//深度严格比较
const util = require('util')
const obj1 = {
a:1,
b:{
c:3
}
};
const obj2 = {
a:1,
b:{
c:3
}
}
console.log(util.isDeepStrictEqual(obj1,obj2)) //->true
①fs模块
readFile
const fs = require('fs')
const path = require('path')
//绝对路径读取
const filename = path.resolve(__dirname,'./myFiles/1.txt')
fs.readFile(filename,(err,content)=>{
console.log(content.toString('utf-8'))
})
const fs = require('fs')
const path = require('path')
const filename = path.resolve(__dirname,'./myFiles/1.txt')
async function test(){
const content = await fs.promises.readFile(filename,'utf-8');
console.log(content)
}
test();
writeFile
const fs = require('fs')
const path = require('path')
const filename = path.resolve(__dirname,'./myFiles/1.txt')
async function test(){
await fs.promises.writeFile(filename,'abc','utf-8');
console.log('成功')
}
test();
const fs = require('fs')
const path = require('path')
const filename = path.resolve(__dirname,'./myFiles/1.txt')
async function test(){
await fs.promises.writeFile(filename,'abcd',{
flag:"a"//追加内容
});
console.log('成功')
}
test();
// copy一个图片
const fs = require('fs')
const path = require('path');
async function test(){
const fromFilename = path.resolve(__dirname,'./myFiles/1.jpg');
const buffer = await fs.promises.readFile(fromFilename);
const toFilename = path.resolve(__dirname,'./myFiles/1.copy.jpg');
await fs.promises.writeFile(toFilename,buffer);
console.log('copy success')
}
test();
stat:获取文件或目录信息
const fs = require('fs')
const path = require('path');
const filename = path.resolve(__dirname,'./myFiles/1.jpg')
async function test(){
const stat = await fs.promises.stat(filename)
console.log(stat)
console.log('是否是目录',stat.isDirectory());
console.log('是否是文件',stat.isFile());
}
test();
获取子文件信息
const fs = require('fs')
const path = require('path');
const dirname = path.resolve(__dirname,'./myFiles/')
async function test(){
const pathes = await fs.promises.readdir(dirname);
console.log(pathes)
}
test();
可读流,可写流,双工流。
创建一个文件可读流:
fs.createReadStream(path[,options])
//可选配置:encoding,start.end,highWaterMark
返回:Readable子类ReadStream
const fs = require("fs");
const path = require("path")
const filename = path.resolve(__dirname,'./1.txt');
const rs = fs.createReadStream(filename,{
encoding:"utf-8",
highWaterMark:1,
autoClose:true,//读完后自动关闭(默认)
})
rs.on("open",()=>{
console.log('dakaile')
})
rs.on("error",()=>{
console.log('error')
})
rs.on("close",()=>{
console.log('close')
})
rs.on("data",chunk=>{
console.log('读到了一部分数据',chunk)
rs.pause();
})
rs.on("pause",()=>{
console.log('pause')
setTimeout(() => {
rs.resume();
},1000)
})
rs.on("end",()=>{
console.log('end')
})
rs.pause()//暂停
rs.resume()//恢复
fs.createWriteStream(path[,options])
const fs = require("fs");
const path = require("path")
const filename = path.resolve(__dirname,'./1.txt');
const ws = fs.createWriteStream(filename,{
// flags:"",
encoding:"utf-8",
// start:"",//起始字节,
highWaterMark:2,//每次最多写入的字节数
});
const flag = ws.write("a");
console.log(flag)
// 会返回一个布尔值
// true:写入通道没有被填满,接下来的数据可以直接写入,无需排队。
// false:写入通道目前已经被填满,接下来的数据将进入写入队列。
ws.on("drain",()=>{
console.log("可以再次写入")
write();
})
ws.end();
//copy一个txt
const fs = require("fs");
const path = require("path")
// const filename = path.resolve(__dirname,'./1.txt');
async function method1(){
const form = path.resolve(__dirname,'./1.txt');
const to = path.resolve(__dirname,'./abc1.txt');
const content = await fs.promises.readFile(form)
await fs.promises.writeFile(to,content);
console.log('复制完成')
}
method1();
//优化后,是减少了,占用内存空间少了
async function method1(){
const form = path.resolve(__dirname,'./1.txt');
const to = path.resolve(__dirname,'./abc1.txt');
const rs = fs.createReadStream(form);
const ws = fs.createWriteStream(to)
rs.on("data",chunk => {
// 读到一部分数据
const flag = ws.write(chunk);
if(!flag){
// 表示会被压
rs.pause();//暂停读取
}
});
ws.on('drain',()=>{
// 可以继续写了
rs.resume();
});
rs.on('close',()=>{
// 写完了
ws.end();
})
}
//pipe()
async function method1(){
const form = path.resolve(__dirname,'./1.txt');
const to = path.resolve(__dirname,'./abc1.txt');
const rs = fs.createReadStream(form);
const ws = fs.createWriteStream(to)
// 把读的东西写到另一个里
// 把可读流写到可写流
rs.pipe(ws)
rs.on("close",()=>{
})
}
method1();
const http = require("http");
//搭建服务器
const server = http.createServer((req,res) => {
console.log("有请求来了")
console.log("请求的地址",req.url);
console.log("请求路径",req.urlobj);
console.log("请求头",req.headers)
let body = ''
req.on('data',chunk => {
body + chunk.toString('ytf-8')
});
req.on('end',chunk=>{
console.log("请求体",body)
});
res.setHeader('a','1')
res.write('你好');
res.end()
})
server.listen(9527);
server.on('listening',()=>{
console.log("server listen 9527")
})
// const request = http.request("http://duyi.ke.qq.com/",{
// method:"GET"
// },
// resp => {
// console.log("服务器已响应",resp.statusCode);
// console.log("服务器响应头",resp.headers);
// resp.on('data',chunk => {
// console.log(chunk)
// })
// }
// );
// request.end();//表示消息体结束
// 写一个静态资源服务器
// http://localhost:9527//index.html ->public/index.html 文件内容
//http://localhost:9527/css/index.css -> public/css/index.css
const http = require("http")
const URL = require("url")
const path = require("path");
const fs = require("fs")
async function getStat(filename){
try{
return await fs.promises.stat(filename);
}catch{
return null
}
}
// 得到处理的文件路径
async function getFileInfo(url){
const urlObj = URL.parse(url);
console.log(urlObj.pathname);
let filename;//要处理的文件路径
filename = path.resolve(__dirname,"public",urlObj.pathname.substr(1))
const stat = await getStat(filename)
console.log(stat)
}
function handler(req,res){
const info = getFileInfo(REQ.url)
res.write('hello')
res.end();
}
const server = http.createServer(handler);
server.on("listening",()=>{
console.log("server listen 6000")
});
server.listen(6000);
timers:存放计时器的回调函数
poll:轮询队列,除了timers,checks绝大部分回调都会放入该队列。比如:文件的内容读取,监听用户请求。
poll队列运作方式:如果poll中有回调,依次执行回调,直到清空队列;如果poll中没有回调,等待其他队列中出现回调,结束该阶段,进入下一阶段。如果其他队列也没有回调,持续等待,直到出现回调为止。
check:检查阶段,使用setImmediate()
时间循环中,每次打算执行一个回调之前,必须要先清空,nextTick和promise队列