Node.js
NodeJS操作文件
引入文件模块
var fs = require("fs");
读取文件
var fs = require("fs");
//此处传入一个utf8之后,读取出来的文件数据就会自动以utf8的编码方式转换成我们能看懂的字符串
//(也可以通过toString()的方式转换)
fs.readFile("./db.json","utf8",function(error,data){
if(error){
return response.status(500).send("Server error.");
}
//从文件中读取到的数据一定是字符串
//所以一定要手动转成对象才能够去渲染模板
var students = JSON.parse(data).students;
});
异步编程(回调函数)
js中的函数
- 是一种数据类型
- 能作为参数
- 能作为返回值
- 非常灵活,无所不能
- 一般情况下,把函数作为参数,就是为了获取函数内部的异步操作结果
- JavaScript 单线程、时间循环
获取函数内部异步操作的结果
无法直接获取:
function add(x,y){
console.log(1);
setTimeout(function(){
console.log(2);
var ret = x+y;
return ret;
},1000);
console.log(3);
//到这里执行就世结束了,不会等到前面的定时器,所以直接就返回了默认值 undefined
}
console.log(add(10,20)); //结果为undefined
使用回调函数获取:
凡是要得到一个函数内部异步操作的结果(setTimeout、readFile、writeFile、ajax),必须通过回调函数,并且异步API都伴有一个回调函数。
function add(x,y,callback){
//callback 就是回调函数
console.log(1);
setTimeout(function(){
var ret = x+y;
callback(ret);
},1000);
}
add(10,20,function(ret){
console.log(ret);
});
基于原生XMLHTTPRequest 封装 get 方法:
function get(url,callback){
var oReq = new XMLHttpRequest();
//当请求加载成功之后要调用指定的函数
oReq.onload = function(){
//现在需要得到这里的 oReq.responseText
callback(oReq.response);
}
oReq.open("get",url,true);
oReq.send();
}
get("./data.json",function(data){
console.log(data);
});
Express
在Express中配置使用 art-template模板引擎
安装:
npm install --svae art-template
npm install --save express-art-template
配置:
app.engine(".html",require("express-art-template"));
使用:
app.get("/admin",function(request,response){
//默认会去views目录下找
//渲染模板时只需要在文件后 加一个数据参数即可
response.render("admin/index.html",{
title : "管理系统"
});
});
Express 获取表单 GET 请求参数
Express 内置了一个API,可以直接通过 request.query 来获取
request.query;
Express 获取表单 POST 请求参数
在Express中没有内置获取表单POST请求体的API,这里我们需要使用一个第三方包: body-parser
安装:
npm install --save body-parser
配置:
//引入express框架
var express = require("express");
//引包
var bodyParser = require("body-parser");
var app = express();
//配置 body-parser
//只要加入这个配置,则在request请求对象上会多出来一个属性:body
//也就是说可以直接通过 request.body来获取表单 post 请求体中的数据了
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
使用:
app.post("/post",function(request,response){
//1、获取表单请求参数
//request.query 只能拿到 get 请求参数
//console.log(request.query);
let comment = request.body;
//2、处理
comment.dateTime = "2019年9月18日 15:29:31";
comments.unshift(comment);
//3、发送响应(重定向到主页)
response.redirect("/");
});
Promise
无法保证顺序的代码:
var fs = require("fs");
fs.readFile("./data/a.txt","utf8",function(error,data){
if(error){
// return console.log("读取失败");
/*
抛出异常
1、阻止程序的执行
2、把错误信息打印到控制台
*/
throw error;
}
console.log(data);
});
fs.readFile("./data/b.txt","utf8",function(error,data){
if(error){
throw error;
}
console.log(data);
});
fs.readFile("./data/c.txt","utf8",function(error,data){
if(error){
throw error;
}
console.log(data);
});
通过回调嵌套的方式来保证顺序:
var fs = require("fs");
fs.readFile("./data/a.txt","utf8",function(error,data){
if(error){
// return console.log("读取失败");
/*
抛出异常
1、阻止程序的执行
2、把错误信息打印到控制台
*/
throw error;
}
console.log(data);
//a执行完毕之后调用b
fs.readFile("./data/b.txt","utf8",function(error,data){
if(error){
throw error;
}
console.log(data);
//b执行完毕之后调用c
fs.readFile("./data/c.txt","utf8",function(error,data){
if(error){
throw error;
}
console.log(data);
});
});
});
为了解决以上编码方式带来的问题(回调地狱嵌套),所以在EcmaScript 6 中新增了一个API:Promise 。
- Promise 的英文就是承诺、保证的意思
- Promise本身不是异步,但是内部往往封装的是异步任务
Promise基本语法:
//在EcmaScript 6 中新增了一个API Promise
//Promise 是一个构造函数
var fs = require("fs");
//创建一个 promise 容器
var p1 = new Promise(function(resolve,reject){//Promise 容器一旦创建就执行里面的代码
fs.readFile("./data/a.txt","utf8",function(error,data){
if(error){
//失败了,承诺容器中的任务失败了
//console.log(error);
//把容器的Pending 状态变为 Rejected
reject(error);
}else{
//承诺容器中的任务成功了
//console.log(data);
//把容器的Pending状态改为成功 Resolved
resolve(data);
}
});
});
Promise链式调用:
var fs = require("fs");
//创建一个 promise 容器
var p1 = new Promise(function(resolve,reject){//Promise 容器一旦创建就执行里面的代码
fs.readFile("./data/a.txt","utf8",function(error,data){//这是一个异步任务
if(error){
//失败了,承诺容器中的任务失败了
//console.log(error);
//把容器的Pending 状态变为 Rejected
reject(error);// ===>失败调用
}else{
//承诺容器中的任务成功了
//console.log(data);
//把容器的Pending状态改为成功 Resolved
resolve(data);// ===>成功调用
}
});
});
var p2 = new Promise(function(resolve,reject){
fs.readFile("./data/b.txt","utf8",function(error,data){
if(error){
reject(error);
}else{
resolve(data);
}
});
});
var p3 = new Promise(function(resolve,reject){
fs.readFile("./data/c.txt","utf8",function(error,data){
if(error){
reject(error);
}else{
resolve(data);
}
});
});
p1.then(function(data){
console.log(data);
/*
当p1读取成功的时候
当前函数中 return 的结果就可以在后面的 then 中的 function 中接受到
当return 123 时,后面就接受到1233
当return "hello" 时,后面就接受到 "hello"
没有 return 后面收到的就是 undefined
上面那些 return 的数据没什么卵用
真正有用的是: 可以 return 一个 Promise 对象
当 return 一个 Promise 对象的时候,后续的 then 中的 function 的第一个参数会作为p2的 resolve
*/
return p2;
},function(error){
console.log(error);
})
.then(function(data){//上面return的什么,这里的data接受到的就是什么,若return的是Promie对象,则此处则将function作为Promise的resolve
console.log(data);
return p3;
})
.then(function(data){
console.log(data);//同理,上面return什么,这里的data就是什么,若return的是Promie对象,则此处则将function作为Promise的resolve
});
封装Promise API:
var fs = require("fs");
//封装
var pReadFile = function(filePath){
return new Promise(function(resolve,reject){
fs.readFile(filePath,function(error,data){
if(error){
reject(error);
} 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);
});
本文来自博客园,作者:奇怪的阿峰,转载请注明原文链接:https://www.cnblogs.com/zhongyufeng/articles/15120686.html

浙公网安备 33010602011771号