Aiden's blog Aiden's blog
首页
  • 前端文章

    • JavaScript
    • Vue
  • 学习笔记

    • JavaScript教程
    • JavaScript高级程序设计
    • ES6 教程
    • Vue
    • Vue3.0
    • React
    • TypeScript 从零实现 axios
    • Git
    • TypeScript
    • JS设计模式总结
    • 小程序
    • 小程序云开发
    • Echarts
    • 微前端
    • H5
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 搜索引擎
  • ES系列
  • 经典面试题
  • 知识点总结
  • uni-app
  • 算法
  • Vue3实战
  • 小程序chatgpt
  • 小程序配网流程
  • 程序WIFI配网
  • 小程序WebSocket
  • H5 WebSocket
  • H5 TTS
  • Vue3实现OSS存储
  • 大文件分片上传
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Aiden Wu

前端界的小学生
首页
  • 前端文章

    • JavaScript
    • Vue
  • 学习笔记

    • JavaScript教程
    • JavaScript高级程序设计
    • ES6 教程
    • Vue
    • Vue3.0
    • React
    • TypeScript 从零实现 axios
    • Git
    • TypeScript
    • JS设计模式总结
    • 小程序
    • 小程序云开发
    • Echarts
    • 微前端
    • H5
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 搜索引擎
  • ES系列
  • 经典面试题
  • 知识点总结
  • uni-app
  • 算法
  • Vue3实战
  • 小程序chatgpt
  • 小程序配网流程
  • 程序WIFI配网
  • 小程序WebSocket
  • H5 WebSocket
  • H5 TTS
  • Vue3实现OSS存储
  • 大文件分片上传
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 技术文档

  • GitHub技巧

  • Nodejs

    • Nodejs递归读取所有文件
    • Nodejs学习笔记
      • Node.js
        • 优缺点
        • 读取文件
        • 写文件
        • http
        • Node中的JavaScript
        • 模板引擎
        • 服务端渲染&客户端渲染
        • 什么是模块化
        • CommonJS模块规范
        • 原理解析
        • exports和module.exports的区别
        • 优先从缓存加载
        • 第三方模块的加载规则
        • package.json
      • npm
        • npm网站
        • npm命令行工具
        • 解决npm被墙问题
      • Buffer
        • 使用
      • Express
        • 文件操作路径和模块标识路径问题
        • 修改完代码自动重启服务器
        • 基本路由
        • 公开静态资源服务
        • Express中的render
        • Express中get请求和post请求
        • 提取路由模块
        • package.json和package-lock.json
        • express案例
      • MongoDB
        • 关系型数据库和非关系型数据库
        • 启动和关闭数据库
        • 连接和推迟数据库
      • 在Node中如何操作MongoDB数据
        • MongoDB数据库的基本概念
        • mongoose
      • Node-MySQL
        • 使用Node操作MySQL数据库
      • Promise
        • Promise基本语法:
        • 封装Promise 版本的readFileAPI:
        • 封装Promise版本的ajax
        • Promise数据库操作
        • Promise用户注册
  • 博客搭建

  • 搜索引擎

  • ES系列

  • 经典面试题

  • 知识点总结

  • uni-app

  • 算法

  • Vue3实战

  • 小程序chatgpt

  • 小程序WIFI配网

  • 小程序配网流程

  • 小程序WebSocket

  • H5 WebSocket

  • H5 TTS

  • Vue3实现OSS存储

  • 大文件分片上传

  • 技术
  • Nodejs
wushengxin
2021-09-30
目录

Nodejs学习笔记

# Node.js

  • Node.js是JavaScript运行时环境
  • Node.js可以解析和执行JavaScript代码
  • 以前只有浏览器可以解析和执行JavaScript代码
  • 现在可以脱离浏览器来运行,一切都归于Node.js
  • Node.js中的JavaScript
    • 没有BOM、DOM
    • EcmaScript
    • 在Node这个JavaScript执行环境中为JavaScript提供了一些服务器级别的操作API
      • 例如文件读写
      • 网络服务的构建
      • 网络通信
      • http服务器

# 优缺点

  • 异步非阻塞的I/O(I/O线程池)
  • 特别适用于I/O密集型应用(对比传统java服务器)
  • 事件循环机制(独有的一套,与浏览器不一样)
  • 单线程(成为单线程,败也单线程)
  • 跨平台(几乎常见语言都支持)

不足之处:

回调函数嵌套太多、太深

单线程,处理不好CPU密集型

# 读取文件

  • 使用require方法加载fs核心模块

  • 第一个参数未读取文件的路径

  • 成功data->数据,error->null,失败data->undefined没有数据,error->错误对象

  • data返回二进制,toString返回文件的信息

const fs = require('fs');
fs.readFile('./data/hello.txt',function(error,data){
  console.log(data.toString())
})
1
2
3
4

# 写文件

  • 第一个参数是文件的名字,可不存在
  • 第二个参数是要写的文件内容
  • 第三个参数是回调函数
  • 当为不规范的文件名时,文件写入失败
const fs = require('fs');
fs.writeFile('./data/hello.md','大家好,我是node.js',function(error){
  if(error){
    console.log('文件写入失败')
  }else{
    console.log('文件写入成功')
  }
})
1
2
3
4
5
6
7
8

# http

  • 帮你创建编写服务器
  • 回调函数request请求对象,response响应对象
  • request.url获取当前请求路径
  • response对象有一个方法:write可以用来给客户端发送请求响应数据,write可以使用多次,但是最后一定要使用end来结束响应,否则客户端会一直等待
  • res.end()响应内容只能是二进制数据或字符串
  • 中文系统默认编码为gbk,服务器默认是utf-8编码,第一个参数内容类型,第二个参数为文本类型
  • 图片就不需要指定编码了
res.setHeader('Content-Type','text/plain;charset=utf-8')
1
//加载http核心模块
const http = require('http')
//使用http.createServer()方法创建一个Web服务器
//返回一个Server实例
const server = http.createServer()
//客户端请求过来,自动触发服务器request请求事件,然后执行第二个参数:回调处理
server.on('request',function (request,response) {
  console.log('收到客户端的请求了!' + request.url)
  console.log('请求我的客户端端口号是:' + request.socket.remotePort)
  console.log('请求我的客户端的ip地址是:' + request.socket.remoteAddress)
  //所有的url都是以/开头的
  const url = request.url;
  if(url=='/index'){
    response.end('hello node.js')
  }else{
    // response.write('hello')
    // response.write(' nodejs')
    response.end('hello world')
  }
  // 结束响应
  // response.end()
})
//绑定端口号,启动服务器
server.listen(3000,function () {
  console.log('服务器启动成功了,可以通过http://127.0.0.1:3000/来进行访问')
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# Node中的JavaScript

  • EcmaScript

    • 没有DOM、BOM
  • 核心模块

    • Node为JavaScript提供了很多服务器级别的API,这些API绝大多数都被包装到了一个具名的核心模块中了,例如文件操作的fs核心模块,http服务构建http模块,path路径操作模块,os操作系统信息模块等
    • 以后只要这个模块是核心模块,就必须
    const fs = require('fs')
    
    1
  • 第三方模块(通信)

    • 模块是完全封闭的,外部无法访问内部,内部也无法访问外部

    • 优点:可以完全避免变量名命名冲突的问题

    • require(模块化编程)=>文件作用域

      • 加载文件模块并执行里面的代码

      • 拿到被加载文件模块导出的接口对象

      • 可以省略后缀名

      • 相对路径必须加./,例如

        require('./os.js')
        require('./os')
        
        1
        2
    • exports

      • 默认是一个空对象

      image-20201020102205592

  • 用户自定义模块

# 模板引擎

  • 安装npm install art-template

# 服务端渲染&客户端渲染

  • 服务端渲染在浏览器中查看网页元素可搜索到,客户端渲染不行
  • 客户端渲染不利于SEO搜索引擎优化,百度很难搜索到
  • 服务端渲染是可以被爬虫抓取到的,客户端异步渲染是很难被爬虫抓取到的
  • 真正的网站是两者结合做的,例如京东的商品列表是服务端渲染的,目的是为了SEO搜索引擎优化,评论是客户端渲染,不需要SEO优化

# 什么是模块化

  • 文件作用域
  • 通信规则
    • 加载require
    • 导出

# CommonJS模块规范

在Node中的JavaScript还有一个很重要的概念,模块系统

  • 模块作用域

  • 使用require方法用来加载模块

  • 使用exports接口对象用来导出模块的成员

  • 如果一个模块需要直接导出某个成员,而不是挂载

    • 导出单个成员,必须使用module.exports = add,拿到的只有一个,后者会覆盖前者

      • 也可以导出多个成员
    • exports和module.exports等价,可以导出多个成员,返回的也是个对象

      module.exports = {
        add:function(){
          return x + y
        },
        str:'hello'
      }
      
      //exports { foo: 'bar', add: [Function] }
      
      1
      2
      3
      4
      5
      6
      7
      8

    exports.foo = 'bar' exports.add = function(x,y){ return x+y }

    
    
    
    - 导出多个成员exports.a = add  (前面的add是变量)
    
    
    
    
    1
    2
    3
    4
    5
    6
    7

# 原理解析

  • exports和module.exports的一个引用
  • 也就是说在模块中有这么一句代码var exports = module.exports
  • 最后return的是module.exports
console.log(exports === module.exports) //true

exports.foo = 'bar'

//等价于
module.exports.foo = 'bar'
1
2
3
4
5
6

# exports和module.exports的区别

image-20201027111723832

# 优先从缓存加载

  • 被require加载过的,将不再调用加载,只执行一次加载

image-20201027112449857

  • 在次调用主要是拿到里面的接口对象
    • 由于在a中加载b了,所以从缓存中加载,只会拿到里面的接口对象,不会再次加载
    • 避免重复加载,提高模块加载效率

image-20201027112641905

# 第三方模块的加载规则

image-20201101153845496

# package.json

  • 建议每个项目都要有一个package.json文件(包描述文件)
  • 这个文件可以通过npm init的方式来自动初始化出来
  • 最有用的是dependencies选项,用来保存第三方包的依赖信息
  • 建议执行npm install都加上--sava,用来保存第三方包的依赖信息
  • 如果node_modoles删除了,已经有第三方依赖包了,直接执行npm install或者npm i是install的简写

image-20201101154901825

# npm

  • node package manager

# npm网站

npmjs.com

# npm命令行工具

  • --save 简写-S,install简写i

  • 只要安装了node就已经安装了npm

  • 查看npm版本npm --version

  • 升级npm,npm install --global npm

  • 常用命令

    • npm iniy -y可以跳过向导,快速生产package.json文件
    • npm install 包名
    • npm install --save 包名
      • 下载并保存依赖项(package.json中的dependencies选项)
      • npm i -S 包名
    • npm install
      • 只下载
      • npm i
    • npm uninstall 包名
      • 只删除,如果有依赖项会依然保存
    • npm uninstall --save 包名
      • 删除的同时会把依赖信息也去除
      • npm un -S 包名
    • npm --help
      • 查看使用帮助
    • npm 命令 --help
      • 查看指定命令的使用帮助
    • cnpm i -S bootstrap@3.3.7
      • 安装指定版本
    • npm view jquery versions
      • 查看jquery的所有版本
    • npm root -g
      • 查看全局安装的地址
    • npm ls jquery
      • 查看当前环境下的版本

# 解决npm被墙问题

  • npm存储包文件的服务器在国外,有时候会被墙,速度很慢,所以我们需要解决这个问题
  • 网站npm.taobao.org
  • 在任意目录下安装淘宝的cnpm,--global表安装全局
    • npm install --global cnpm
  • 接下来安装包的时候把之前的npm替换成cnpm
  • 如果不想安装cnpm又想使用淘宝的服务器下载
    • npm config set proxy https://registry.npm.taobao.org
    • 查看npm配置信息
      • npm config list

# Buffer

接受客户端的数据(视频、图片等)

  • 类数组,用来存储数据(二进制数据)
  • 效率高
  • Buffer的大小一旦确定了,不可修改
  • 灭个元素占用内存的大小为1字节
  • Buffer是Node中的核心模块,无需下载,无需引入

# 使用

new一个Buffer实例,性能差

使用性能好的

  1. Buffer.alloc()
  2. Buffer.allocUnsafe()
  • Buffer.from将数据存入一个Buffer实例
    • 为什么是二进制的:用户存储的不一定是字符串,可能是媒体类型的文件

# Express

  • 原生的http在某些方面表现不足以应对我们的开发需求,所以我们就需要使用框架来加快我们的开发效率,框架的目的就是提高效率,让我们的代码更高度统一
  • 在Node中,有很多Web开发框架,我们这以学习express为主
  • 网站expressjs.com
  • get请求在express中可以直接req.query来获取查询字符串参数
// 引包
const express = require('express')
// 创建服务器应用程序,也就是原来的http.createServer
const app = express()

// 公开指定目录
app.use('/public/',express.static('./public/'))

app.get('/',function(req,res){
  res.send('hello express')
})
app.get('/about',function(req,res){
  // 在express中可以直接req.query来获取查询字符串参数
  console.log(req.query)
  res.send('你好,我是express!')
})

app.listen(3000,function(){
  console.log('app is running at port 3000.')
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 文件操作路径和模块标识路径问题

  • 文件操作(fs)中的相对路径可以省略./
  • 在模块加载中,相对路径中的./不能省略,.js可以省略
  • 所有文件操作的API都是异步的

# 修改完代码自动重启服务器

  • 第三方命名航工具:nodemon来解决修改代码重启服务器问题
  • nodemon是一个基于Node.js开发的一个第三方命令行工具
  • 需要安装cnpm install --global nodemon
  • 安装完后,使用nodemon app.js自动重启服务器

# 基本路由

  • 路由器
    • 请求方法get,post
    • 请求路径
    • 请求处理函数

# 公开静态资源服务

  • 当省略第一个参数的时候,则可以通过省略/public的方式来访问
  • 访问时直接写文件名即可,不用加/public,直接public文件下的资源
// 引包
const express = require('express')
// 创建服务器应用程序,也就是原来的http.createServer
const app = express()

// 公开指定目录
//当以/public/开头的时候,去./public/目录中找对应的资源
app.use('/public/',express.static('./public/'))

//当省略第一个参数的时候,则可以通过省略/public的方式来访问
//访问时直接写文件名即可,不用加/public
app.use(express.static('./public/'))

app.get('/',function(req,res){
  res.send('hello express')
})
app.get('/about',function(req,res){
  // 在express中可以直接req.query来获取查询字符串参数
  console.log(req.query)
  res.send('你好,我是express!')
})

app.listen(3000,function(){
  console.log('app is running at port 3000.')
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# Express中的render

express中默认不存在render渲染数据,render只有安装了模板引擎才有

  • 安装
npm install --save art-template
npm install --save express-art-template
1
2
  • 配置
// view engine setup
app.engine('html', require('express-art-template'));
1
2

# Express中get请求和post请求

  • get请求获取表单参数通过req.query

  • post请求获取请求体数据,没有内置获取post请求的api

    • 通过express 的middleware
    • 安装npm install --save body-parser
    • 配置
    var express = require('express')
    //引包
    var bodyParser = require('body-parser')
    
    var app = express()
    
    //配置body-parser
    //只要配置了,就可以通过req.body来获取post请求的请求体数据了
    // parse application/x-www-form-urlencoded
    app.use(bodyParser.urlencoded({ extended: false }))
    // parse application/json
    app.use(bodyParser.json())
    
    app.use(function (req, res) {
      res.setHeader('Content-Type', 'text/plain')
      res.write('you posted:\n')
        //通过req.body来获取请求体数据
      res.end(JSON.stringify(req.body, null, 2))
    })
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    • 通过req.body获取请求参数

# 提取路由模块

router.js

const fs = require('fs')

const express = require('express')
// 创建路由容器
const router = express.Router()
// 把路由挂载到router路由容器中
router.get('/students',function(req,res){
  fs.readFile('./db.json','utf8',function(err,data){
    if(err){
      return res.status(500).send('Server error.')
    }
    const students = JSON.parse(data).students
    res.render('index.html',{
      fruits:[
        '苹果',
        '香蕉',
        '橘子'
      ],
      students
    })
  })
})

router.get('/students/new',function(req,res){
  res.render('new.html')
})  

router.post('/students/new',function(req,res){
  // 获取表单的数据
  // console.log(req.body)
  // 处理,将数据保存在db.json中

  // 发送响应
})

router.post('/students/edit',function(req,res){

})

router.get('/students/delete',function(req,res){

})
// 导出router
module.exports = router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

app.js

const router = require('./router')
// 把路由容器挂载到app服务中
app.use(router)
1
2
3

# package.json和package-lock.json

  • npm5以前没有package-lock.json这个文件
  • npm5以后才加入了这个文件
  • 当年安装包的时候,npm都会生产或者更新package-lock.json这个文件
  • npm5以后版本安装包不需要加--save参数,它会自动保存依赖信息
  • 当你安装包的时候,会自动创建package-lock.json这个文件
  • package-lock.json会保存node_modules中所有包的信息(版本,下载地址)
    • 重新npm i的时候下载的速度会快很多
    • 锁定版本号,防止自动升级新版
    • ^锁定大版本
    • ~锁定小版本

# express案例

image-20210717104022215

# MongoDB

# 关系型数据库和非关系型数据库

表就是关系,或者说表与表之间存在关系

  • 所有的关系型数据库都要通过sql语言来操作

  • 所有的关系型数据库在操作之前都需要设计表结构

  • 而且数据表还支持约束

    • 唯一的
    • 主键
    • 默认值
    • 非空
  • 非关系型数据库非常的灵活

  • 有的非关系型数据库就是key-value键值对

  • 但是MongoDB是长的最像关系型数据库的非关系型数据库

    • 数据库->数据库
    • 数据表->集合
    • 记录->文档对象
  • MongoDB不需要设计表结构

  • 安装 (opens new window)

    • community Server
  • 配置环境用户变量Path

    • C:\Program Files\MongoDB\Server\4.4\bin
      
      1
  • 验证是否安装成功mongod --version

注意:不支持事务,复杂查询时语句过于频繁

# 启动和关闭数据库

启动

  1. 在C盘下手动新建/data/db(在哪执行的命令就在哪个盘建
  2. 执行命令mongod
  3. 如果想要修改数据存储目录,可以:mongod --dbpath=数据存储路径

停止

  1. 开启服务的控制台ctrl+c
  2. 直接关闭服务的控制台

# 连接和推迟数据库

连接

  • 直接执行mongo命令

退出

  • 执行exit

# 基本命令

  • show dbs
    • 查看显示所有数据库
  • show collections
    • 查看当前操作的数据库的集合
  • db
    • 查看当前操作的数据库
  • use 数据库名称
    • 切换到指定的数据库(如果没有会新建)
  • 插入数据
    • db.students.insertOne({"name": "Jack"})
  • 查看插入的数据
    • db.students.find()
    • 查看更多数据
      • it

# 在Node中如何操作MongoDB数据

# MongoDB数据库的基本概念

  • 数据库
  • 集合
  • 文档
  • 指定连接的数据库不存在,当你插入第一条数据后被创建
{
	//数据库
	qq:{
	    //集合
		users:[
			//一条记录一个对象(文档)
			{name:"张三",age:15},
			{},
			{}
		],
		products:[
		
		]
	},
	taobao{
	
	}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# mongoose

  • 使用第三方mongoose在操作MongeDB数据库
  • mongoose官网 (opens new window)
  • 第三方包:mongoose基于MongoDB官方mongodb包再次封装
  • 安装mongoose,npm i --save mongoose

hello word:

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
//设计集合结构(表结构)
const Cat = mongoose.model('Cat', { name: String });

const kitty = new Cat({ name: 'Zildjian' });
kitty.save().then(() => console.log('meow'));
1
2
3
4
5
6
7
# 设计Schema发布model
const mongoose = require('mongoose');
const Schema = mongoose.Schema

//1.指定连接的数据库不存在,当你插入第一条数据后被创建
mongoose.connect('mongodb://localhost/test');

//2.设计集合结构
let userSchema = new Schema({
  username:{
    type:String,
    required:true
  },
  password:{
    type:String,
    required:true
  },
  email:{
    type:String
  }
});

// 3.将文档结构发布为模型
//mongoose.model方法就是将一个架构发布为一个model
//第一个参数,传入一个大写名词单数字符串来标识你的数据库名称
//mongoose会自动将大写名词字符串生成小写复数的集合名称
//第一个参数:架构Schema
// 返回值:模型构造函数
let User = mongoose.model('User', userSchema);
//4.使用构造函数对users集合中的数据为所欲为了,增删改查
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 增加数据
let admin = new User({
  username:"admin",
  password:"123456",
  email:"admin@admin.com"
})

admin.save(function(err,ret){
  if(err){
    console.log('保存失败')
  }else{
    console.log('保存成功')
    console.log(ret)
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 查询数据
//查询所有数据
User.find(function(err,ret){
  if(err){
    console.log('查询失败')
  }else{
    console.log(ret);
  }
})

//单独查一个条数据(数组)
User.find({
  username:'zs'
},function(err,ret){
  if(err){
    console.log('查询失败')
  }else{
    console.log(ret);
  }
})

//单独查一个条数据(数组中的第一条数据,对象)
User.findOne({
  username:'zs'
},function(err,ret){
  if(err){
    console.log('查询失败')
  }else{
    console.log(ret);
  }
})

//查插入的第一条数据(对象)
User.findOne(function(err,ret){
  if(err){
    console.log('查询失败')
  }else{
    console.log(ret);
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 删除数据

根据条件删除一个:

Model.findOneAndRemove(conditions,[options],[callback])
1

根据id删除一个:

Model.findByIdAndRemove(id,[options],[callback])
1
//删除
//删除所有zs用户
User.remove({
  username:'zs'
},function(err,ret){
  if(err){
    console.log('删除失败')
  }else{
    console.log('删除成功')
    console.log(ret)
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
# 更新数据
  • 第一个参数为id
  • 第二个参数为要更改的数据
  • 第三个参数为回调函数

根据条件更新所有

Model.update(conditions,doc,[options],[callback])
1

根据指定条件更新一个:

Model.findOneAndUpdate([conditions],[update],[options],[callback])
1

根据id更新一个:

User.findByIdAndUpdate('5fae9d0f7b967b3b9cf51177',{
  password:'123'
},function(err,ret){
  if(err){
    console.log('更新失败')
  }else{
    console.log('更新成功')
    console.log(ret)
  }
})
1
2
3
4
5
6
7
8
9
10

# Node-MySQL

# 使用Node操作MySQL数据库

安装:

npm install --save mysql
1

npm官网找mysql

实例:增删改查步骤一样

var mysql = require('mysql');
// 1.创建mysql数据库
var connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'root',
  database: 'users'
});
// 2.连接mysql数据库
connection.connect();
//3.执行数据操作
connection.query('SELECT * FROM `users`', function (error, results, fields) {
  if (error) throw error;
  console.log('The solution is: ', results);
});
// NULL自动生成id
// connection.query('INSERT INTO users VALUES("NULL","admin","123456")', function (error, results, fields) {
//   if (error) throw error;
//   console.log('The solution is: ', results);
// });
//4.关闭连接
connection.end();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# Promise

  • 解决异步回调地狱嵌套promise,方便代码维护
  • 第一个then方法接收的function就是容器中的resolve
  • 调用的resolve方法就是then方法传递的function
  • 调用的reject相当于调用了then方法的第二个参数
  • 第二个的data为第一个then方法return的数据
  • 第二个then中如果第一个then中没有return,则为undefined
  • 多个then链式调用异步编程

image-20201114220502910

# Promise基本语法:

let fs = require('fs')


let p1 = new Promise(function (resolve,reject){
  fs.readFile('./data/hello.txt','utf8',function(err,data){
    if(err){
      reject(err)
    }else{
      //这里调用的resolve方法就是then方法传递的function
      resolve(data)
    }
  })
})


let p2 = new Promise(function (resolve,reject){
  fs.readFile('./data/hello.md','utf8',function(err,data){
    if(err){
      reject(err)
    }else{
      //这里调用的resolve方法就是then方法传递的function
      resolve(data)
    }
  })
})
//链式调用异步编程
p1.
  then(function(data){
    console.log(data)
    //当p1读取成功之后
    return p2
  },function(err){
    console.log('读取文件失败了',err)
  })
  .then(function(data){
    console.log(data)
  })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

# 封装Promise 版本的readFileAPI:

let fs = require('fs')

function pReadFile(filePath){
  return new Promise(function (resolve,reject){
    fs.readFile(filePath,'utf8',function(err,data){
      if(err){
        reject(err)
      }else{
        //这里调用的resolve方法就是then方法传递的function
        resolve(data)
      }
    })
  })
}

pReadFile('./data/hello.txt')
  .then(function(data){
    console.log(data)
    return pReadFile('./data/hello.md')
  })
  .then(function(data){
    console.log(data)
  })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 封装Promise版本的ajax

pGet('http://127.0.0.1:3000/students')
  .then(function(data){
    console.log(data)
  })

function pGet(url){
  return new Promise(function(resolve,reject){
    let xhr = new XMLHttpRequest()
    xhr.onload = function(){
      resolve(JSON.parse(xhr.responseText))
    }
    xhr.onerror = function(err){
      reject(err)
    }
    xhr.open('get',url)
    xhr.send()
  })    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# Promise数据库操作

# Promise用户注册

//用户注册
// 1.判断用户是否存在
// 如果存在,结束注册
// 如果不存在,注册
User.findOne({
  username:'aaa'
})
.then(function(user){
  if(user){
    //用户已存在,不能注册
    console.log('用户已存在')
  }else{
    //用户不存在,可以注册
    return new User({
      username:'aaa',
      password:'123',
      email:'abcdefg'
    }).save()
  }
})
  .then(function(ret){
    console.log('注册成功')
  })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
编辑 (opens new window)
上次更新: 2021/12/06, 21:28:32
Nodejs递归读取所有文件
解决百度无法收录搭建在GitHub上的个人博客的问题

← Nodejs递归读取所有文件 解决百度无法收录搭建在GitHub上的个人博客的问题→

最近更新
01
大文件分片上传
08-05
02
Vue3实现OSS存储
08-05
03
H5 TTS
08-05
更多文章>
Theme by Vdoing | Copyright © 2019-2025 Aiden Wu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×