您的位置:首页 > 健康 > 美食 > 黑龙江省建设厅官网查询_开发助手app_柳州今日头条新闻_广告网络推广

黑龙江省建设厅官网查询_开发助手app_柳州今日头条新闻_广告网络推广

2025/1/4 18:27:58 来源:https://blog.csdn.net/qq_34568700/article/details/106219844  浏览:    关键词:黑龙江省建设厅官网查询_开发助手app_柳州今日头条新闻_广告网络推广
黑龙江省建设厅官网查询_开发助手app_柳州今日头条新闻_广告网络推广

Node.js 是什么

  • Node.js 不是一门语言,不是库、不是框架,Node.js 是一个 JavaScript 运行时环境,可以解析和执行 JavaScript 代码,以前只有浏览器可以可以解析执行 JavaScript 代码,现在的 JavaScript 可以完全脱离浏览器来运行,一切都归功于:Node.js
  • 浏览器中的 JavaScript有EcmaScript,BOM, DOM,Node.js 中的 JavaScript没有 BOM、DOM,
  • 在 Node 这个 JavaScript 执行环境中为 JavaScript 提供了一些服务器级别的操作 API
    • 例如文件读写
    • 网络服务的构建
    • 网络通信
    • http 服务器
    • 等处理。。。
  • 构建与 Chrome 的 V8 引擎之上,Google Chrome 的 V8 引擎是目前公认的解析执行 JavaScript 代码最快的,Node.js 的作者把 Google Chrome 中的 V8 引擎移植了出来,开发了一个独立的 JavaScript 运行时环境。
  • 特点
    • event-driven 事件驱动
    • non-blocking I/O model 非阻塞IO模型(异步)
    • lightweight and efficient. 轻量和高效

Node.js 能做什么

  • Web 服务器后台
  • 命令行工具
    • npm(node)
    • git(c 语言)
    • hexo(node)
  • 对于前端开发工程师来讲,接触 node 最多的是它的命令行工具
    • webpack
    • gulp
    • npm

本文知识简介

  • B/S 编程模型
    • Browser - Server
    • back-end
    • 任何服务端技术这种 BS 编程模型都是一样,和语言无关
  • 模块化编程
    • RequireJS
    • SeaJS
    • @import('文件路径'),在 Node 中可以像 @import() 一样来引用加载 JavaScript 脚本文件
  • Node常用API
  • 异步编程
    • 回调函数
    • Promise
    • async
    • generator
  • Express Web 开发框架

起步

解析执行 JavaScript
  1. 创建编写 JavaScript 脚本文件
  2. 打开终端,定位到脚本文件所属目录
  3. 输入 node 文件名 执行对应的文件

注意:文件名不要使用 node.js 来命名,也就是说除了 node 这个名字你随便起,而且最好也不要使用中文。

文件读写

浏览器中的 JavaScript 是没有文件操作的能力的,但是 Node 中的 JavaScript 具有文件操作的能力

fs 是 file-system 的简写,就是文件系统的意思,在 Node 中如果想要进行文件操作,就必须引入 fs 这个核心模块,在 fs 这个核心模块中,就提供了所有的文件操作相关的 API

// 1. 使用 require 方法加载 fs 核心模块
var fs = require('fs')// 2. 读取文件
//    第一个参数就是要读取的文件路径
//    第二个参数是一个回调函数  
//        读取成功
//          data 等于数据
//          error 等于null
//        读取失败
//          data 等于undefined没有数据
//          error 等于错误对象
fs.readFile('./data/a.txt', function (error, data) {// 文件中存储的其实都是二进制数据 0 1,// 可以通过 toString 方法把其转为我们能认识的字符// console.log(data)// console.log(error)// 在这里就可以通过判断 error 来确认是否有错误发生if (error) {console.log('读取文件失败了')} else {console.log(data.toString())}
})

文件写入:

var fs = require('fs')
// 第一个参数:文件路径
// 第二个参数:文件内容
// 第三个参数:回调函数
//    error:
//      文件写入成功,error 是 null
//      文件写入失败,error 就是错误对象
fs.writeFile('./data/你好.md', '大家好,给大家介绍一下,我是Node.js', function (error) {// console.log(error)if (error) {console.log('写入失败')} else {console.log('写入成功了')}
})
http

在 Node 中专门提供了一个核心模块:http,这个模块的职责就是帮你创建编写服务器的

// 1. 加载 http 核心模块
var http = require('http')// 2. 使用 http.createServer() 方法创建一个 Web 服务器
//    返回一个 Server 实例
var server = http.createServer()// 3. 服务器要干嘛?提供服务:数据的服务;发请求;接收请求;处理请求;发送响应
//    注册 request 请求事件
//    当客户端请求过来,就会自动触发服务器的 request 请求事件,然后执行第二个参数:回调处理函数
server.on('request', function () {console.log('收到客户端的请求了')
})// 4. 绑定端口号,启动服务器
server.listen(3000, function () {console.log('服务器启动成功了,可以通过 http://127.0.0.1:3000/ 来进行访问')
})

Node 中的 JavaScript

  • EcmaScript 语言
    • 和浏览器不一样,在 Node 中没有 BOM、DOM
  • 核心模块
    • 文件操作的 fs
    • http 服务的 http
    • url 路径操作模块
    • path 路径处理模块
    • os 操作系统信息
  • 第三方模块
    • art-template
    • 必须通过 npm 来下载才可以使用
  • 自己写的模块
    • 自己创建的文件

EcmaScript

核心模块

Node 为 JavaScript 提供了很多服务器级别的 API ,这些 API 绝大多数都被包装到了一个具名的核心模块中了。例如文件操作的 fs 核心模块,http 服务构建的 http 模块,path 路径操作模块、os 操作系统信息模块。如果想要使用它,就必须先使用 require 方法加载才能使用:

var fs = require('fs')
var http = require('http')

ip 地址和端口号

  • ip 地址用来定位计算机
  • 端口号用来定位具体的应用程序,一切需要联网通信的软件都会占用一个端口号,端口号的范围从 0 - 65536 之间。在计算机中有一些默认端口号,最好不要去使用,例如 http 服务的 80
  • 我们在开发过程中使用一些简单好记的端口号就可以了,例如 3000、5000 等没什么含义
  • 可以同时开启多个服务,但一定要确保不同服务占用的端口号不一致才可以,即在一台计算机中,同一个端口号同一时间只能被一个程序占用

在 Node 中使用模板引擎

安装:

$ npm install art-template

使用:

var template = require('art-template')var ret = template.render('hello {{ name }}', {name: 'Jack'
})console.log(ret) // => hello Jack

CommonJS 模块规范

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

  • 模块作用域
  • 使用 require 方法用来加载模块
  • 使用 exports 接口对象用来导出模块中的成员
加载 require

语法:

var 自定义变量名称 = require('模块')

两个作用:

  • 执行被加载模块中的代码
  • 得到被加载模块中的 exports 导出接口对象
导出 exports
  • Node 中是模块作用域,默认文件中所有的成员只在当前文件模块有效
  • 对于希望可以被其它模块访问的成员,我们就需要把这些公开的成员都挂载到 exports 接口对象中就可以了

导出多个成员(必须在对象中):

exports.a = 123
exports.b = 'hello'
exports.c = function () {console.log('ccc')
}
exports.d = {foo: 'bar'
}

导出多个成员也可以这么来写:

module.exports = {foo: 'bar',add: function () {}
}

导出单个成员(拿到的就是:函数、字符串):

module.exports = 'hello'

以下情况会覆盖:

module.exports = 'hello'// 以这个为准,后者会覆盖前者
module.exports = function (x, y) {return x + y
}

也可以这样来导出多个成员:

module.exports = {add: function () {return x + y},str: 'hello'
}
原理解析

exports 和 module.exports 的一个引用:

// var module = {
//   exports = {}
// }
// var exports = module.exportsconsole.log(exports === module.exports) // => trueexports.foo = 'bar'// 等价于
moudle.exports.foo = 'bar'// return module.exports
exports 和 module.exports 的区别
  • exports 和 module.exports 的区别
    • 每个模块中都有一个 module 对象,module 对象中有一个 exports 对象, 我们可以把需要导出的成员都挂载到 module.exports 接口对象中 也就是:moudle.exports.xxx = xxx 的方式
    • 但是每次都 moudle.exports.xxx = xxx 很麻烦,所以 Node 为了你方便,同时在每一个模块中都提供了一个成员叫:exports
      exports === module.exports 结果为 true
      所以对于:moudle.exports.xxx = xxx 的方式 完全可以:expots.xxx = xxx
    • 当一个模块需要导出单个成员的时候,这个时候必须使用:module.exports = xxx 的方式, 不要使用 exports = xxx 不管用,因为每个模块最终向外 return 的是 module.exports, 而 exports 只是 module.exports 的一个引用, 所以即便你为 exports = xx 重新赋值,也不会影响 module.exports
    • 但是有一种赋值方式比较特殊:exports = module.exports 这个用来重新建立引用关系的
require 方法加载规则
  • 优先从缓存加载
  • 判断模块标识
    • 核心模块
    • 第三方模块
    • 自己写的模块
  • 路径形式的模块:
    ./ 当前目录,不可省略
    …/ 上一级目录,不可省略
    /xxx 几乎不用 (首位的 / 在这里表示的是当前文件模块所属磁盘根路径)
    d:/a/foo.js 几乎不用
    .js 后缀名可以省略
     require('./foo.js')
    
  • 核心模块的本质也是文件,核心模块文件已经被编译到了二进制文件中了,我们只需要按照名字来加载就可以了
    require('fs')
    require('http')
    
  • 第三方模块
    凡是第三方模块都必须通过 npm 来下载
    使用的时候就可以通过 require(‘包名’) 的方式来进行加载才可以使用
    不可能有任何一个第三方包和核心模块的名字是一样的
    加载art-template示例:找到node_modules/art-template/package.json 文件中的 main 属性,main 属性中就记录了 art-template 的入口模块,然后加载使用这个第三方包
    如果 package.json 文件不存在或者 main 指定的入口模块是也没有,则 node 会自动找该目录下的 index.js,也就是说 index.js 会作为一个默认备选项
    如果以上所有任何一个条件都不成立,则会进入上一级目录中的node_modules 目录查找,如果上一级还没有,则继续往上上一级查找, 如果直到当前磁盘根目录还找不到,最后报错:can not find module xxx
    var template = require('art-template')
    
npm 命令行工具

npm 也有版本这个概念。

npm --version

升级 npm(自己升级自己):

npm install --global npm
常用命令
  • npm init
    • npm init -y 可以跳过向导,快速生成
  • npm install
    • 一次性把 dependencies 选项中的依赖项全部安装
    • npm i
  • npm install 包名
    • 只下载
    • npm i 包名
  • npm install --save 包名
    • 下载并且保存依赖项(package.json 文件中的 dependencies 选项)
    • npm i -S 包名
  • npm uninstall 包名
    • 只删除,如果有依赖项会依然保存
    • npm un 包名
  • npm uninstall --save 包名
    • 删除的同时也会把依赖信息也去除
    • npm un -S 包名
  • npm help
    • 查看使用帮助
  • npm 命令 --help
    • 查看指定命令的使用帮助
    • 例如我忘记了 uninstall 命令的简写了,这个时候,可以输入 npm uninstall --help 来查看使用帮助
解决 npm 被墙问题

npm 存储包文件的服务器在国外,有时候会被墙,速度很慢,所以我们需要解决这个问题。

http://npm.taobao.org/ 淘宝的开发团队把 npm 在国内做了一个备份。

安装淘宝的 cnpm:

# 在任意目录执行都可以
# --global 表示安装到全局,而非当前目录
# --global 不能省略,否则不管用
npm install --global cnpm

接下来你安装包的时候把之前的 npm 替换成 cnpm

举个例子:

# 这里还是走国外的 npm 服务器,速度比较慢
npm install jquery# 使用 cnpm 就会通过淘宝的服务器来下载 jquery
cnpm install jquery

如果不想安装 cnpm 又想使用淘宝的服务器来下载:

npm install jquery --registry=https://registry.npm.taobao.org

但是每一次手动这样加参数很麻烦,所我们可以把这个选项加入配置文件中:

# 配置到淘宝服务器
npm config set registry https://registry.npm.taobao.org# 查看 npm 配置信息
npm config list

只要经过了上面命令的配置,则你以后所有的 npm install 都会默认通过淘宝的服务器来下载。

package.json

建议每一个项目都要有一个 package.json 文件(包描述文件,就像产品的说明书一样),这个文件可以通过 npm init 的方式来自动初始化出来。

package.json中的 dependencies 选项,可以用来帮我们保存第三方包的依赖信息。这样如果你的 node_modules 删除了也不用担心,只需要:npm install 就会自动把 package.json 中的 dependencies 中所有的依赖项都下载回来。

  • 建议每个项目的根目录下都有一个 package.json 文件
  • 建议执行 npm install 包名的 的时候都加上 --save 这个选项,目的是用来保存依赖项信息
package.json 和 package-lock.json

npm 5 以前是不会有 package-lock.json 这个文件的,npm 5 以后才加入了这个文件,当你安装包的时候,npm 都会生成或者更新 package-lock.json 这个文件。

  • npm 5 以后的版本安装包不需要加 --save 参数,它会自动保存依赖信息
  • 当你安装包的时候,会自动创建或者是更新 package-lock.json 这个文件
  • package-lock.json 这个文件会保存 node_modules 中所有包的信息(版本、下载地址),这样的话重新 npm install 的时候速度就可以提升
  • 从文件来看,有一个 lock 称之为锁,这个 lock 是用来锁定版本的。如果项目依赖了 1.1.1 版本,没有package-lock时重新 install 其实会下载最新版本,而不是 1.1.1,有package-lock可以锁住 1.1.1 这个版本,防止自动升级新版

Express

原生的 http 在某些方面表现不足以应对我们的开发需求,所以我们就需要使用框架来加快我们的开发效率,框架的目的就是提高效率,让我们的代码更高度统一。

安装
npm install --save express
hello world
const express = require('express')
const app = express()app.get('/', (req, res) => res.send('Hello World!'))app.listen(3000, () => console.log('Example app listening on port 3000!'))
基本路由
  • 请求方法
  • 请求路径
  • 请求处理函数

get:

// 当你以 GET 方法请求 / 的时候,执行对应的处理函数
app.get('/', function (req, res) {res.send('Hello World!')
})

post:

// 当你以 POST 方法请求 / 的时候,指定对应的处理函数
app.post('/', function (req, res) {res.send('Got a POST request')
})
静态服务
// /public资源
app.use(express.static('public'))// /files资源
app.use(express.static('files'))// /public/xxx
app.use('/public', express.static('public'))// /static/xxx
app.use('/static', express.static('public'))app.use('/static', express.static(path.join(__dirname, 'public')))

配置 art-template 模板引擎

安装:

npm install --save art-template
npm install --save express-art-template

配置:

// 第一个参数用来配置视图的后缀名,这里是 art ,则你存储在 views 目录中的模板文件必须是 xxx.art
// app.engine('art', require('express-art-template'))// 这里我把 art 改为 html
app.engine('html', require('express-art-template'))

使用:

app.get('/', function (req, res) {// express 默认会去项目中的 views 目录找 index.htmlres.render('index.html', {title: 'hello world'})
})

如果希望修改默认的 views 视图渲染存储目录,可以:

// 注意:第一个参数 views 千万不要写错
app.set('views', 目录路径)

在 Express 中获取表单 GET 请求参数

Express 内置了一个 API,可以直接通过 req.query 来获取

req.query

在 Express 获取表单 POST 请求体数据

在 Express 中没有内置获取表单 POST 请求体的 API,这里我们需要使用一个第三方包:body-parser

安装:

npm install --save body-parser

配置:

var express = require('express')
// 0. 引包
var bodyParser = require('body-parser')var app = express()// 配置 body-parser
// 只要加入这个配置,则在 req 请求对象上会多出来一个属性:body
// 也就是说你就可以直接通过 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 来获取表单 POST 请求体数据res.end(JSON.stringify(req.body, null, 2))
})
路由设计
请求方法请求路径get 参数post 参数备注
GET/studens渲染首页
GET/students/new渲染添加学生页面
POST/studens/newname、age、gender、hobbies处理添加学生请求
GET/students/editid渲染编辑页面
POST/studens/editid、name、age、gender、hobbies处理编辑请求
GET/students/deleteid处理删除请求
提取路由模块

router.js:

/*** router.js 路由模块* 职责:*   处理路由*   根据不同的请求方法+请求路径设置具体的请求处理函数* 模块职责要单一,不要乱写* 我们划分模块的目的就是为了增强项目代码的可维护性* 提升开发效率*/
var express = require('express')// 1. 创建一个路由容器
var router = express.Router()// 2. 把路由都挂载到 router 路由容器中
router.get('/students', function (req, res) {
})router.get('/students/new', function (req, res) {
})router.post('/students/new', function (req, res) {
})router.get('/students/edit', function (req, res) {
})router.post('/students/edit', function (req, res) {
})router.get('/students/delete', function (req, res) {
})// 3. 把 router 导出
module.exports = router

app.js:

var router = require('./router')// 挂载路由
app.use(router)
设计操作数据的 API 文件模块
/*** student.js* 数据操作文件模块* 职责:操作文件中的数据,只处理数据,不关心业务*//*** 获取所有学生列表* return []*/
exports.find = function () {}/*** 添加保存学生*/
exports.save = function () {}/*** 更新学生*/
exports.update = function () {}/*** 删除学生*/
exports.delete = function () {}
自己编写的步骤
  • 处理模板
  • 配置开放静态资源
  • 配置模板引擎
  • 简单路由:/students 渲染静态页出来
  • 路由设计
  • 提取路由模块
  • 由于接下来一些列的业务操作都需要处理文件数据,所以我们需要封装 student.js
  • 先写好 student.js 文件结构
    • 查询所有学生列表的 API find
    • findByid
    • save
    • updateById
    • deleteById
  • 实现具体功能
    • 通过路由收到请求
    • 接收请求中的数据(get、post)
      • req.query
      • req.body
    • 调用数据操作 API 处理数据
    • 根据操作结果给客户端发送响应
  • 业务功能顺序
    • 列表
    • 添加
    • 编辑
    • 删除
  • find
  • findIndex

MongoDB

参考 http://www.runoob.com/mongodb/mongodb-tutorial.html

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

表就是关系

或者说表与表之间存在关系。

  • 所有的关系型数据库都需要通过 sql 语言来操作
  • 所有的关系型数据库在操作之前都需要设计表结构
  • 而且数据表还支持约束
    • 唯一的
    • 主键
    • 默认值
    • 非空
  • 非关系型数据库非常的灵活
  • 有的非关系型数据库就是 key-value 对儿
  • 但是 MongoDB 是长的最想关系型数据库的非关系型数据库
    • 数据库 -》数据库
    • 数据表-》集合(数组)
    • 表记录-》(文档对象)
  • MongoDB 不需要设计表结构
  • 也就是说你可以任意的往里面存数据,没有结构性这么一说

安装

  • 下载
    • 64 位下载地址:https://www.mongodb.org/dl/win32/x86_64-2008plus-ssl?_ga=2.105676933.746703754.1509930046-961479447.1509930046
    • 32 位下载地址:https://www.mongodb.org/dl/win32/i386
  • 安装
  • 配置环境变量
  • 最后输入 mongod --version 测试是否安装成功

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EdiOHG2d-1589879868803)(media/1509940577391.png)]

启动和关闭数据库

启动:

# mongodb 默认使用执行 mongod 命令所处盘符根目录下的 /data/db 作为自己的数据存储目录
# 所以在第一次执行该命令之前先自己手动新建一个 /data/db
mongod

如果想要修改默认的数据存储目录,可以:

mongod --dbpath=数据存储目录路径

停止:

在开启服务的控制台,直接 Ctrl+c 即可停止。
或者直接关闭开启服务的控制台也可以。

连接和退出数据库

连接:

# 该命令默认连接本机的 MongoDB 服务
mongo

退出:

# 在连接状态输入 exit 退出连接
exit

基本命令

  • show dbs
    • 查看显示所有数据库
  • db
    • 查看当前操作的数据库
  • use 数据库名称
    • 切换到指定的数据(如果没有会新建)
  • 插入数据

mongoose

官方的 mongodb 包来操作:https://github.com/mongodb/node-mongodb-native

第三方包:mongoose 基于 MongoDB 官方的 mongodb 包再一次做了封装。

  • 网址:http://mongoosejs.com/

异步编程

回调函数

不成立的情况:

function add(x, y) {console.log(1)setTimeout(function () {console.log(2)var ret = x + yreturn ret}, 1000)console.log(3)// 到这里执行就结束了,不会等到前面的定时器,所以直接就返回了默认值 undefined
}console.log(add(10, 20)) // => undefined

不成立的情况:

function add(x, y) {var retconsole.log(1)setTimeout(function () {console.log(2)ret = x + y}, 1000)console.log(3)return ret
}console.log(add(10, 20)) // => undefined

回调函数:

如果我讲到这种程度了,说明一个问题,没有认知能力()

如何熟练达到像定义一个变量一样来封装一个带有回调函数的方法。

主要原因在于写得少,这是 JavaScript 编程的一大特色:异步编程。

甚至很多具有服务端开发经验的都不太容易熟悉这种方式。

function add(x, y, callback) {// callback 就是回调函数// var x = 10// var y = 20// var callback = function (a) { }console.log(1)setTimeout(function () {var ret = x + ycallback(ret)}, 1000)
}add(10, 20, function (a) {// a 才是我们得到的结果
})

基于原生 XMLHTTPRequest 封装 get 方法:

function get(url, callback) {var oReq = new XMLHttpRequest()// 当请求加载成功之后要调用指定的函数oReq.onload = function () {// 我现在需要得到这里的 oReq.responseTextcallback(oReq.responseText)}oReq.open("get", url, true)oReq.send()
}get('data.json', function (data) {console.log(data)
})

Promise

参考文档:http://es6.ruanyifeng.com/#docs/promise

callback hell:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-622wlEhO-1589879868805)(media/1509967270775.png)]

无法保证顺序的代码:

var fs = require('fs')fs.readFile('./data/a.txt', 'utf8', function (err, data) {if (err) {// return console.log('读取失败')// 抛出异常//    1. 阻止程序的执行//    2. 把错误消息打印到控制台throw err}console.log(data)
})fs.readFile('./data/b.txt', 'utf8', function (err, data) {if (err) {// return console.log('读取失败')// 抛出异常//    1. 阻止程序的执行//    2. 把错误消息打印到控制台throw err}console.log(data)
})fs.readFile('./data/c.txt', 'utf8', function (err, data) {if (err) {// return console.log('读取失败')// 抛出异常//    1. 阻止程序的执行//    2. 把错误消息打印到控制台throw err}console.log(data)
})

通过回调嵌套的方式来保证顺序:

var fs = require('fs')fs.readFile('./data/a.txt', 'utf8', function (err, data) {if (err) {// return console.log('读取失败')// 抛出异常//    1. 阻止程序的执行//    2. 把错误消息打印到控制台throw err}console.log(data)fs.readFile('./data/b.txt', 'utf8', function (err, data) {if (err) {// return console.log('读取失败')// 抛出异常//    1. 阻止程序的执行//    2. 把错误消息打印到控制台throw err}console.log(data)fs.readFile('./data/c.txt', 'utf8', function (err, data) {if (err) {// return console.log('读取失败')// 抛出异常//    1. 阻止程序的执行//    2. 把错误消息打印到控制台throw err}console.log(data)})})
})

为了解决以上编码方式带来的问题(回调地狱嵌套),所以在 EcmaScript 6 中新增了一个 API:Promise

  • Promise 的英文就是承诺、保证的意思(I promise you)

Promise 基本语法:

var fs = require('fs')// 在 EcmaScript 6 中新增了一个 API Promise
// Promise 是一个构造函数// 创建 Promise 容器
// 1. 给别人一个承诺 I promise you.
//    Promise 容器一旦创建,就开始执行里面的代码
var p1 = new Promise(function (resolve, reject) {// console.log(2)fs.readFile('./data/aa.txt', 'utf8', function (err, data) {if (err) {// 失败了,承诺容器中的任务失败了// console.log(err)// 把容器的 Pending 状态变为 Rejected// 调用 reject 就相当于调用了 then 方法的第二个参数函数reject(err)} else {// console.log(3)// 承诺容器中的任务成功了// console.log(data)// 把容器的 Pending 状态改为成功 Resolved// 也就是说这里调用的 resolve 方法实际上就是 then 方法传递的那个 functionresolve(data)}})
})// console.log(4)// p1 就是那个承若
// 当 p1 成功了 然后(then) 做指定的操作
// then 方法接收的 function 就是容器中的 resolve 函数
p1.then(function (data) {console.log(data)}, function (err) {console.log('读取文件失败了', err)})

封装 Promise 版本的 readFile:

var 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(data)}})})
}pReadFile('./data/a.txt').then(function (data) {console.log(data)return pReadFile('./data/b.txt')}).then(function (data) {console.log(data)return pReadFile('./data/c.txt')}).then(function (data) {console.log(data)})

其它

代码风格

  • Airbnb JavaScript Style
    • 更专业规范,比较严谨
  • JavaScript Standard Style
    • 符合大多数人的习惯

规范只是建议,可以遵守也可以不遵守,在一些比较专业的团队中,对于代码风格会有对应的风格校验工具,如果你的代码风格有问题,例如少了一个空格或者多了一个空格,你的代码都是不允许提交的。

后面会学习如何使用工具来强制校验代码风格的问题。

代码无分号问题

无论你是否使用的是无分号的代码风格规范,都建议当一行代码是以:

  • (
  • [
  • `

以上三者开头的的时候,最好都在其之前补上一个分号。

例如:

;(function () {// code here
})()

修改完代码自动重启

我们这里可以使用一个第三方命名航工具:nodemon 来帮我们解决频繁修改代码重启服务器问题。

nodemon 是一个基于Node.js 开发的一个第三方命令行工具,我们使用的时候需要独立安装:

# 在任意目录执行该命令都可以
# 也就是说,所有需要 --global 来安装的包都可以在任意目录执行
npm install --global nodemon

安装完毕之后,使用:

node app.js# 使用 nodemon
nodemon app.js

只要是通过 nodemon app.js 启动的服务,则它会监视你的文件变化, 当文件发生变化的时候,自动帮你重启服务器。

文件操作路径和模块路径

文件操作路径:

// 在文件操作的相对路径中
//    ./data/a.txt 相对于当前目录
//    data/a.txt   相对于当前目录
//    /data/a.txt  绝对路径,当前文件模块所处磁盘根目录
//    c:/xx/xx...  绝对路径
// fs.readFile('./data/a.txt', function (err, data) {
//   if (err) {
//     console.log(err)
//     return console.log('读取失败')
//   }
//   console.log(data.toString())
// })

模块操作路径:

// 这里如果忽略了 . 则也是磁盘根目录
require('/data/foo.js')// 相对路径
require('./data/foo.js')// 模块加载的路径中的相对路径不能省略 ./

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com