2019-02-12 16 JavaScript进阶

Node.Js

  • 基础模块
    • fs文件读写模块
      • 读文件require('fs').readFile('sample.txt', 'utf-8', function (err, data){});
      • 写文件require('fs').writeFile('output.txt', data, function(err) {})
      • 获取文件大小, 创建时间等信息require('fs').stat('sample.txt', function(err, stat) {})
    • stream数据结构
      • 读文件流
  var rs = require('fs').createReadStream('sample.txt', 'utf-8');
  // data事件表示流的数据可获取
  rs.on('data', function (chunk) {});
  // end事件表示流已到末尾
  rs.on('end', function() {});
  // error事件表示出错
  rs.on('error', function() {});

- 写文件流
      var ws = require('fs').createWriteStream('sample.txt', 'utf-8');
      ws.write('xxxxxxx');
      ws.end();
- http模块
var http = require('http');
// request对象封装HTTP请求, request对象可获取HTTP请求信息
// response对象封装HTTP响应
var server = http.createServer(function (request, response){});
server.listen(8080);
  • web开发
    • koa
// app.js, 在package.json文件的{"main":"app.js"}配置
const Koa = require('koa');
// koa对象, 表示web app对象
var app = new Koa();
app.use(async (ctx, next) => {
  console.log('${ctx.request.method} ${ctx.request.url}');// 打印URL
  await next(); // 调用下一个middleware, 即下一个async函数
})
app.use(async (ctx, next) => {
  await next();
  ctx.response.type = 'text/html';
  ctx.response.body = '<h1>Hello, Koa</h1>';
});

// koa 路由
// require('koa-router')()返回函数调用
const router = require('koa-router')();
router.get('/hello:/:name', async (ctx, next) => {
  // hello页面逻辑
});
// add router middleware
app.use(router.routes());

  • Nunjucks(模板引擎)
const nunjucks = require('nunjucks');
function createEnv(path, opts) {
  ...
  return env;
}
var env = createEnv('views', {
  watch: true,
  filters: {
    hex: function(n) {
      return '0x' + n.toString(16);
    }
  }
});

var s = env.render('hello.html', {name: '小明'});
  • MVC
    • 当用户通过浏览器访问URL, koa接受请求并调用async (ctx, next) => {}处理该URL(也可以通过路由转发到对应的模块处理), 在异步函数内部生成HTML, 最后输出给浏览器, ctx.render('home.html', {name: 'Michael'})
    • 此时Controller为异步函数, 负责业务逻辑, 检查用户名等
    • View为HTML/HTML模板, 负责显示逻辑
    • Model即{name: 'Michael'}
  • mocha(单元测试框架)
    • 支持before, after, beforeEach, afterEach
  • WebSocket(浏览器和服务器双向通信通道)
  // 创建WebSocket Server
  const WebSocket = require('ws');
  // 引用Server类
  const WebSocketServer = WebSocket.Server;
  // 实例化
  const wss = new WebSocketServer({port:3000});

  wss.on('connection', function(ws) {
    ws.on('message', function(message) {
      ws.send(`ECHO:${message}`, (err) => {
        ...
      });
    });
  });

  // 创建WebSocket Client链接...
  var ws = new WebSocket('ws://localhost:3000/test');
  ws.onmessage = function(msg) {console.log(msg);};
  ws.send('hello');
  • REST(处理HTTP请求的async函数, 特点: 1. 除GET外, POST等其它请求BODY均为JSON格式, 2. 响应返回结果均为JSON数据格式)
  const app = new Koa();
  const controller = require('./controller');
  // parse request body..
  app.use(bodyParser());
  // add controller
  app.use(controller());

  app.listen(3000);

  // 暴露访问接口...
  module.exports = {
    'GET /api/products':async (ctx, next) => {
      ctx.response.type = 'application/json';
      ctx.response.body = {...};
    }
  }
  • MVVM
    • Angular, Google出品, 很难用
    • Backbone.js, 入门困难
    • Ember, 大而全
    • Vue.js, 简单支持扩展, 推荐, 看vuejs基础语法教程;

ejs

  • 输出HTML字符串
  // 方法一
  var template = ejs.compile(str, options);
  template(data);
  // 方法二
  ejs.render(str, data, options);
  // 方法三
  ejs.renderFile(filename, data, options, function(err, str) {

  });
  • 标签含义
    • <%, 脚本标签, 用于流程控制, 无输出
    • <%_, 删除前面的空格符
    • <%=输出数据到模板(输出转移HTML模板)
    • <%-输出非转义的数据到模板
    • <%#注释标签
    • <%%输出字符串<%
    • %>结束标签
    • -%>删除紧随的换行符
    • _%>将结束标签后面的空格符删除
  • 包含
    • include引入相对于模板路径的模板
  // 模板
  <ul>
    <% users.forEach(function(user) { %>
      <%- include('user/show', {user: user}) %>
    <% }); %>
  </ul>
  • 自定义分隔符
// 单个模板文件
ejs.render('<?= users.join(" | "); ?>', {users: users},
    {delimiter: '?'});
// => 'geddy | neil | alex'

// 全局
ejs.delimiter = '$';
ejs.render('<$= users.join(" | "); $>', {users: users});

2.15.4 参考文档