翼度科技»论坛 编程开发 JavaScript 查看内容

nodejs 入门基本操作

8

主题

8

帖子

24

积分

新手上路

Rank: 1

积分
24
操作fs模块
  1. const path = require("path");
  2. const fs = require("fs");
  3. /*
  4. 相对路径是命令窗口执行的目录
  5. node 提供了path模块来操作路径相关的api, 其中__dirname是一个内置的变量,返回当前文件所在的目录
  6. */
  7. const getDirUrl = dir => {
  8.   return path.resolve(__dirname, dir);
  9. };
  10. for (let i = 0; i < 5; i++) {
  11.   fs.writeFileSync(getDirUrl("./create01.text"), i + "、我是测试数据" + i + "\n", {
  12.     flag: "a+",
  13.     encoding: "utf-8"
  14.   });
  15. }
  16. console.log("hello nodejs");
  17. const data = fs.readFileSync(getDirUrl("./create01.text"), {encoding: 'utf-8'}).toString()
  18. console.log('同步读取')
  19. console.log(data)
  20. console.log('异步读取')
  21. fs.readFile(getDirUrl("./create01.text"), (err, data) => {
  22.   if(!err) {
  23.     console.log(data.toString());
  24.   } else {
  25.     console.error(err);
  26.   }
  27. });
复制代码
在窗口执行对应的目录即可,我这里是:

操作http模块
  1. // 1. 导入http模块
  2. const http = require("http");
  3. const fs = require("fs");
  4. const path = require("path");
  5. const mimes = {
  6.   html: "text/html",
  7.   css: "text/css",
  8.   js: "text/javascript",
  9.   png: "image/png",
  10.   jpg: "image/jpeg",
  11.   gif: "image/gif",
  12.   mp4: "video/mp4",
  13.   mp3: "audio/mpeg",
  14.   json: "application/json"
  15. };
  16. //2. 创建服务对象 create 创建 server 服务
  17. // request 意为请求. 是对请求报文的封装对象, 通过 request 对象可以获得请求报文的数据
  18. // response 意为响应. 是对响应报文的封装对象, 通过 response 对象可以设置响应报文
  19. const server = http.createServer((req, res) => {
  20.   let { url, method } = req;
  21.   // 文件夹路径
  22.   const rootDir = __dirname + "/public";
  23.    
  24.   let filePath = rootDir + url;
  25.   if (!fs.existsSync(filePath)) {
  26.     return
  27.   }
  28.   // 读取内容
  29.   fs.readFile(filePath, (err, data) => {
  30.     if (err) {
  31.       console.log(err);
  32.       //设置字符集
  33.       res.setHeader('content-type','text/html;charset=utf-8');
  34.       //判断错误的代号
  35.       switch(err.code){
  36.         case 'ENOENT':
  37.           res.statusCode = 404;
  38.           res.end('<h1>404 Not Found</h1>');
  39.         case 'EPERM':
  40.           res.statusCode = 403;
  41.           res.end('<h1>403 Forbidden</h1>');
  42.         default:
  43.           res.statusCode = 500;
  44.           res.end('<h1>500 Internal Server Error</h1>');
  45.       }
  46.       return;
  47.     }
  48.     //获取文件的后缀名
  49.     let ext = path.extname(filePath).slice(1);
  50.     //获取对应的类型
  51.     let type = mimes[ext];
  52.     if(type){
  53.       if(ext === 'html'){
  54.         res.setHeader('content-type', type + ';charset=utf-8');
  55.       }else{
  56.         res.setHeader('content-type', type);
  57.       }
  58.     }else{
  59.       //没有匹配到-默认设置二进制文件类型
  60.       res.setHeader('content-type', 'application/octet-stream');
  61.     }
  62.     //响应文件内容
  63.     res.end(data);
  64.   });
  65. });
  66. //3. 监听端口, 启动服务
  67. server.listen(9000, () => {
  68.   console.log("服务已经启动,9000端口监听中...");
  69. });
复制代码
如上最简单的http 服务起来了,在浏览器中 输入 http://localhost:9000/index.html 得到如下页面

通过匹配后缀,在public文件中返回对应的资源,代码结构如下

都是一些很简单的代码就不贴了,如果需要留下邮箱即可。
其他模块看看官网的文档即可,不在记录。
框架

上面都是通过原始的方式来使用node,其实node的生态也很丰富,有很多的框架让我们选择,如 express、koa2、nestjs、midwayjs 等等
express 基本使用
  1. // 1.0 导入express
  2. const express = require('express')
  3. // 2.0 express 实例
  4. const app = express()
  5. const port = 9000
  6. // 3.0 路由
  7. app.get('/', (req, res) => {
  8.   res.send('基本使用 Hello World!')
  9. })
  10. // 启动服务
  11. app.listen(port, () => {
  12.   console.log(`启动服务,端口: ${port}`)
  13. })
复制代码
通常我们使用脚手架,这样可以得到统一的项目结构 如 express_ generator,具体查看express 官网
中间件-洋葱模型

  目前比较流行的 nodejs http 服务框架使用拦截器模式,这种模式将 http 请求响应的过程分为若干切面,每个切面上进行一项或若干项关联的操作。比如说,我们可以通过不同的拦截切面处理用户信息验证、会话(session)验证、表单数据验证、query 解析,或者业务逻辑处理等等。这种架构设计让切面与切面之间彼此独立。
有点面向切面编程的概念,不知道对不对。
手动实现一个拦截器:实现类似如下效果
  1. async (ctx, next) => {
  2.   do sth...
  3. }
复制代码
通过调用next 执行下一个函数,可以中途return退出,也可以继续调用next直到最后一个函数,然后在一层一层的返回,洋葱的结构跟这个类似,所以叫洋葱模型。
这里的中间件其实是一个函数,在外层使用use 注入进来。

执行第一个中间件的fn,调用next 进入到下一个中间件,继续执行下一个fn,调用next 友进入下一个中间件,继续重复上述逻辑,直至最后一个中间件,直至最后一个中间件,就会执行 next 语句后面的代码,然后继续上一个中间件的next后置语句,继续重复上述逻辑,直至执行第一个中间件的next后置语句,最后输出,这个执行的机制,称为洋葱模型。 模拟洋葱模型

 洋葱模型关键在于怎么处理next 参数,next是下一个函数的引用, ,可以通过我们索引加闭包,或者累加器的形式来处理,为了方便直接使用累加器的形式即可,如下代码:
  1. /*
  2.   这个思路通过利用累加器函数的特性,返回一个函数
  3. */
  4. class Interceptor {
  5.   aspects = [];
  6.   use (fn) {
  7.     this.aspects.push(fn)
  8.     return this
  9.   }
  10.   async run (context) {
  11.     // 从右往左开始遍历
  12.     const proc = this.aspects.reduceRight(
  13.       function (a, b) {
  14.         let flag = false
  15.         return async () => {
  16.           // a 上一个fn,也就是调用的时传入的 next
  17.           if (flag) {
  18.             return
  19.           }
  20.           flag = true
  21.           await b(context, a)
  22.         }
  23.     },() => Promise.resolve())
  24.     try {
  25.       // 通过这个reduceRight 让函数串起来了
  26.       await proc()
  27.     } catch (e) {
  28.       console.error(e);
  29.     }
  30.   }
  31. }
  32. // 测试
  33. const inter = new Interceptor()
  34. inter.use(function a(context, next) {
  35.   console.log("a");
  36.   next();
  37.   console.log("a_after");
  38. });
  39. inter.use(function b(context, next) {
  40.   console.log("b");
  41.   next();
  42.   console.log("b_after");
  43. });
  44. inter.use(function c(context, next) {
  45.   console.log("c");
  46.   next();
  47.   console.log("c_after");
  48. });
  49. inter.use(function d(context, next) {
  50.   console.log("d");
  51.   next();
  52.   console.log("d_after");
  53. });
  54. inter.run();
复制代码
输出a、b、c、d、d_after、c_after、b_after、a_after 其中koa2 源码中使用了索引加闭包的形式来处理 源码

小结

  理解了nodejs 写起来还是挺顺手的,官网文档也还好。至于其他如sql、路由、保持会话状态等后台基本知识点,看看相关文档即可,并没有什么难度。
  nodejs 入门基本也结束了。

来源:https://www.cnblogs.com/longbensong/p/17403467.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具