nodejs-day02

181 阅读5分钟

1.模块化

1. 模块化

在一个js文件中引入另一个js文件就叫做模块化。

1.1 前端方案

  • AMD require.js

  • CMD sea.js

1.2 node的模块化CommonJS

Node 应用由模块组成,采用 CommonJS 模块规范。

1.2.1 CommonJS 特性

  • 引入 require

  • 暴露 exports module.exports global

  • 标识符 module

1.2.3 exports module.exports global 区别

当exports和 module.exports 同时存在的时候指向,以后者为主,建议以后使用暴露的时候使用 module.exports

global 只适合做单个属性全局共享

2. 面试七连击 (重点)

  • 什么是回调函数

    所谓的回调函数,就是在一个函数中把另一个函数当做参数使用,调用的同时传递数据

  • 回调函数的使用场景

    一般用于ajax请求或者不能立即获取到数据

  • 回调函数的缺陷

    多层嵌套的时候会产生回调地狱

  • 如何解决回调函数的缺陷

    Promise

  • Promise的特性

    Promise 是一个对象也是一个构造函数 new Promise

    Promise 需要传递一个箭头函数,箭头函数有两个主要的参数 resolve ,reject

    Promise 的原型上有一个then函数

  • Promise有什么缺陷

    代码量多了不少

  • 如何解决Promise的缺陷

    Promise.all()

    es7 async await

3. 包

模块、文件、资源整合在一起的文件夹

3.1 包的结构

  • lib || src 存放源码

  • dist 提供给用户使用

  • test 测试

  • readme.md 说明文档

  • package.json

    • name 包的名称

    • version 包的版本

    • main 入口文件

3.2 包的查找规则

  • 自定义包

    相对路径包 --> package.json --> main --> index.js

  • 第三方包

    nodule_modules --> package.json --> main --> index.js

3.3 包的管理 npm|cnpm|yarn

  1. npm 既是包的管理也是一个网站

npm init -y 初始化node项目

npm install 包名 -S|-D|-g -S上线依赖 -D开发依赖 -g装到全局(当做工具nodeman)

npm uninstall 包名 -S|-D|-g

npm i 根据package.json 安装依赖包

npm config set registry registry.npm.taobao.org 配置淘宝镜像

npm config get registry 查看镜像

  1. cnpm

npm install -g cnpm --registry=registry.npm.taobao.org

cnpm init -y 初始化node项目

cnpm install 包名 -S|-D|-g -S上线依赖 -D开发依赖 -g装到全局(当做工具nodeman)

cnpm uninstall 包名 -S|-D|-g

cnpm i 根据package.json 安装依赖包

  1. yarn (异步装包,速度稍微快一点)

npm i yarn -g

yarn --version 查看版本

yarn add 包名 包名 -S|-D 安装

yarn remove 包名 包名 -S|-D 卸载

yarn 根据package.json 安装依赖包

4. web服务

4.1 http的请求模型

客户端 ---> 发送请求 ---> 服务端

服务端 ---> 响应 ---> 客户端

4.2 服务器相关

域名 方便记忆

ip 服务器的地址

dns 映射域名和ip的关系

端口号 划分提供不同的服务

4.3 服务器和客户端的区别

客户端:享用资源

服务端:提供资源

java  

  Tomcat  

php  

  Apache 

    phpstudy  

    wamp  (window)

    mamp (mac)

node  

  手写服务  

4.4 手写web服务 (了解)

4.5 使用express创建web服务 (重点)

服务器搭建

静态资源托管

常见的api

node 原生的

res.end 

express提供的

res.send express 提供的  

res.json 返回对象

res.sendFile 获取单个静态资源

res.redirect  重定向   

2.回调函数模拟

function getData(callback) {
 setTimeout(() => {
   var data = 100
   // callback && callback(data)
   if (callback) {
     callback(data)
   }
 }, 1000)
}

getData()

getData(function (data) {
 console.log(data)
})

3.回调地狱

const fs = require('fs')

function getFileData(url, callback) {
 fs.readFile(url, 'utf8', (err, data) => {
   if (err) return callback && callback(err)
   callback && callback(data)
 })
}

getFileData('./files/1.txt', function (data) {
 console.log(data)
 getFileData('./files/2.txt', function (data) {
   console.log(data)
   getFileData('./files/3.txt', function (data) {
     console.log(data)
   })
 })
})

4.使用promise改写回调地狱

const fs = require('fs')

function getFileData(url) {
 return new Promise((resolve, reject) => {
   fs.readFile(url, 'utf8', (err, data) => {
     if (err) return reject(err)
     resolve(data)
   })
 })
}


// 错误示范
// getFileData('./files/1.txt').then(function (data) {
//   console.log(data)
//   getFileData('./files/2.txt').then(function (data) {
//     console.log(data)
//     getFileData('./files/3.txt').then(function (data) {
//       console.log(data)
//     })
//   })
// })

// getFileData('./files/1111.txt')
//   .then(data => {
//     console.log(data)
//     return getFileData('./files/2.txt')
//   }, function (err) {
//     console.log(err)
//   })
//   .then(data => {
//     console.log(data)
//     return getFileData('./files/3.txt')
//   }, function (err) {
//     console.log(err)
//   })
//   .then(data => {
//     console.log(data)
//   }, function (err) {
//     console.log(err)
//   })
// .catch(err => {
//   console.log(err)
// })

// 按照数组的索引执行 返回总的结果
// Promise.all([getFileData('./files/3.txt'), getFileData('./files/22.txt'), getFileData('./files/1.txt')])
//   .then(datas => {
//     console.log(datas)
//   })
//   .catch(err => {
//     console.log(err)
//   })


// // 谁先执行返回谁的结果 
// Promise.race([getFileData('./files/3.txt'), getFileData('./files/2.txt'), getFileData('./files/1.txt')]).then(data => {
//   console.log(data)
// })

// es7 async await    


async function getData() {
 try {
   const data1 = await getFileData('./files/1.txt')
   const data2 = await getFileData('./files/22.txt')
   const data3 = await getFileData('./files/3.txt')
   console.log(data1)
   console.log(data2)
   console.log(data3)
 } catch (error) {
   console.log(error)
 }
}

getData()

5.使用自定义calc包

// const calc = require('./calc/src')
const calc = require('calc')

console.log(calc.add(1, 2))
console.log(calc.sub(1, 2))
  • calc文件夹中
  • add.js:
// function add(x, y) {
//   return x + y
// } 

// module.exports = add

module.exports = (x, y) => x + y
  • sub.js
function sub(x, y) {
return x - y
}

module.exports = sub
  • index.js
const add = require('./add.js')
const sub = require('./sub.js')


// console.log(add(1, 2))
// console.log(sub(1, 2))

module.exports = {
add,
sub
}

6.使用第三方包

const $ = require('jquery')

console.log($)

7.手写web服务

  • 1.引入http模块
const http=require('http')
  • 2.创建服务器
const app=http.createServer()
  • 3.监听客户端请求
    • req: 客户端的请求对象
    • res:服务端的响应对象
app.on('request',(req,res)=>{
    console.log('来了老弟')
    res.end('hello node')
})
  • 4.监听端口号
// 参数1 port 端口号
// 参数2 host ip 默认值为 localhost||127.0.0.1  可以设置成数组 
// 参数3 callback  
// app.listen(3000, ['10.41.153.32', '127.0.0.1'], () => {
app.listen(3000, ['127.0.0.1'], () => {
  console.log('本地服务 http://127.0.0.1:3000')
  console.log('局域网服务 http://10.41.153.32:3000')
})

8.根据请求返回不同的资源

const fs = require('fs')
const path = require('path')
// 1. 引入http模块
const http = require('http')

// 2. 创建服务器 
const app = http.createServer()

// 3. 监听客户端请求 
app.on('request', (req, res) => {
  if (req.url === '/index.html') {
    fs.readFile(path.join(__dirname, './views/index.html'), (err, data) => {
      if (err) return console.log(err.message)
      res.end(data)
    })
  } else if (req.url === '/about.html') {
    fs.readFile(path.join(__dirname, './views/about.html'), (err, data) => {
      if (err) return console.log(err.message)
      res.end(data)
    })
  } if (req.url === '/api/post' && req.method === 'POST') {
    res.end('post')
  } if (req.url === '/1.png') {
    fs.readFile(path.join(__dirname, './views/1.png'), (err, data) => {
      if (err) return console.log(err.message)
      res.end(data)
    })
  }
})
// 4. 监听端口号  
app.listen(3000, () => {
  console.log('本地服务 http://127.0.0.1:3000')
})
  • res.end()与res.send()的区别 res.end只能支持两种参数,要么字符串,要么Buffer res.send可以支持多种参数,比如可以传json对象,Buffer,String,Array

The body parameter can be a Buffer object, a String, an object, or an Array. For example:

res.send()参数可传可不传 res.send()内部自动帮发送更过的相应报文头,比如其中的Content-Type为UTF-8

9.静态资源托管

const fs = require('fs')
const path = require('path')
// 1. 引入http模块
const http = require('http')

// 2. 创建服务器 
const app = http.createServer()

// 3. 监听客户端请求 
app.on('request', async (req, res) => {
  // getStaticFile(req.url).then(data => {
  //   res.end(data)
  // })
  const data = await getStaticFile(req.url)
  res.end(data)
})

// 4. 监听端口号  
app.listen(3000, () => {
  console.log('本地服务 http://127.0.0.1:3000')
})

// function getStaticFile(url, res) {
//   fs.readFile(path.join(__dirname, './views', url), (err, data) => {
//     if (err) return console.log(err.message)
//     res.end(data)
//   })
// }

function getStaticFile(url) {
  return new Promise((resolve, reject) => {
    fs.readFile(path.join(__dirname, './views', url), (err, data) => {
      if (err) return reject(err.message)
      resolve(data)
    })
  })
}
// 1. 引入express   
const express = require('express')
const path = require('path')

// 2. 创建服务 
const app = express()

// 静态资源托管 
// http://127.0.0.1
// app.use(express.static(path.join(__dirname, './views')))
// http://127.0.0.1/images
// app.use('/images', express.static(path.join(__dirname, './images')))

app.get('/', (req, res) => {
  // res.end('hello express')
  res.redirect('/index.html')
})

// 返回整个页面
app.get('/index.html', (req, res) => {
  // res.end('首页')
  // res.send('首页')
  res.sendFile(path.join(__dirname, './views/index.html'))
})


// // 返回整个页面
// app.get('/about.html', (req, res) => {
//   // res.end('首页')
//   // res.send('首页')
//   res.sendFile(path.join(__dirname, './views/about.html'))
// })
// 返回接口
app.get('/api/data', (req, res) => {
  // res.end('hello express')
  res.json({
    status: 200,
    message: [
      {
        id: 0,
        name: 'fly'
      }
    ]
  })
})

app.post('/api/post', (req, res) => {
  res.end('post')
})


app.listen(8888, () => {
  console.log('http://127.0.0.1:8888')
})