Node.js学习笔记 day05、day06

1.接收客户端数据的语法

1.1GET方式

1.1.1
  • 客户端请求:/api/xx?id=1
  • 接口写法:app.get(‘api/xx’,(req,res) => { })
  • 接口参数:req.body
1.1.2
  • 客户端请求:/api/xx/1
  • 接口写法:app.get(’/api/xx/:id’)
  • 接口参数:req.params

1.2POST方式

1.2.1
  • 客户端:content-type:application/x-www-form-urlencoded
  • 中间件:app.use(express.urlencoded({extended:false}))
  • 接口写法:app.post(‘api/xx’,(req,res) => { })
  • 接口参数:req.body
1.2.2
  • 客户端:content-type:multipart/form-data
  • 加载multer模板:const multer = require(‘multer’)
  • 配置上传目录:const upload = multer({dest:‘uploads’})
  • 接口写法:app.post(‘api/xx’,upload.single(’ '),(req,res) => { })
  • 接口参数:req.bodyreq.file

2.跨域

2.1同源策略

  • 协议、主机地址、端口组成一个**“源”**
  • 如果两个url的协议、主机地址、端口都相同,那么这两个url是同源的,否则就是非同源
  • 如果非同源,那么以下三种行为会受到限制:Cookie 无法操作、DOM 无法操作、Ajax请求无效(请求可以发送,服务器也会处理这次请求,但是响应结果会被浏览器拦截)

2.2解决跨域

  • 主流的方案有两种:分别是JSONPCORS
2.2.1JSONP
  • JSONP是程序员被迫想出来的解决跨域的方案
  • JSONP方案和Ajax没有任何关系
  • JSONP方案只支持GET请求
  • JSONP没有浏览器兼容问题,任何浏览器都支持
  • 原理:
    • 客户端利用 script 标签的 src 属性,去请求一个接口,因为src属性不受跨域影响
    • 服务端响应一个字符串
    • 客户端接收到字符串,然后把它当做JS代码运行
  • ajax可以通过dataType:jsonp发起跨域请求
2.2.2CORS
  • CORS方案,就是通过服务器设置响应头来实现跨域
  • CORS才是解决跨域的真正解决方案
  • 前端无需做任何事情,正常发送Ajax请求即可
  • 后端需要加响应头,或者使用第三方模块cors

3.ES6模块化

  • 模块化的好处
    1. 模块化可以避免命名冲突的问题
    2. 大家都遵守同样的模块化规范写代码,降低了沟通的成本,极大方便了各个模块之间的相互调用
    3. 只需关心当前模块本身的功能开发,需要其他模块的支持时,在模块内调用目标模块即可

3.1在nodejs中使用es6模块

  • 确保安装了 v13.0.0或更高版本的 node.js
  • 在 package.json 的根节点中添加 ==“type”: “module” ==节点
3.1.1导入导出方法1
  • 导出方法1:import obj from ’ ./ .js’
  • 导入方法1:export default{ }
  • 导入方法中的路径前缀后缀都要写
  • 这种方法导出的数据在导入时不能解构
3.1.2导入导出方法2
  • 导出方法1:import {a,b,fn1} from ’ ./ .js’
  • 导入方法2:export let a= ;export let b= ;
  • export + 变量定义导出的数据,必须解构
  • fn1 as f,把函数名fn2改为f
3.1.3导入导出方法3
  • 第三种导入导出使用的是逻辑而不是导出的对象
  • 直接用import导出

4.Promise

  • 回调地狱:如果我们希望几个异步请求按照顺序来执行,那么就需要将这些异步操作嵌套起来,嵌套的层数特别多,就会形成回调地狱 或者叫做 横向金字塔

4.1Promise语法

  • Promise对象可以解决回调地狱的问题
  • Promise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和更强大
  • Promise可以理解为一个容器,里面可以编写异步程序的代码
  • 从语法上说,Promise 是一个对象,使用的使用需要 new
  • 使用:
//es6导入fs模块
import fs from 'fs';
//resolve:异步操作成功,请通过;需要传递参数
//reject:异步操作失败。拒绝;需要传递失败的对象
let p = new Promise((resolve,reject) => {
    //Promise参数的函数中的代码,必须是异步
    fs.readFile('./txt/a.txt','utf8',(err,data) => {
        //判断err
        if(err == null){//err为null,说明异步成功,参数交给resovle处理
            resolve(data);
        }else{
            reject(err);
        };
    });
});
//方法1:处理结果  then()有两个形参,第一个处理成功,第二个处理失败
p.then(function (results){
    console.log(results)
},function(err){
    console.log('异步操作失败,原因是:' + err.message);
});
//方法2:then()处理成功,catch()处理失败
p.then(function(results){
    console.log(results);
}).catch(function(err){
    console.log(err);
});
  • Promise解决回调地狱
  • 使用:
import fs from 'fs';
let p1 = new Promise((resolve,reject) => {
    fs.readFile('./txt/a.txt','utf8',(err,data) => {
        resolve(data);
    });
});
let p2 = new Promise((resolve,reject) => {
    fs.readFile('./txt/b.txt','utf8',(err,data) => {
        resolve(data);
    });
});
let p3 = new Promise((resolve,reject) => {
    fs.readFile('./txt/c.txt','utf8',(err,data) => {
        resolve(data);
    });
});
//Promise对象的then()处理结果
p1.then(res => {
    console.log(res);
    //then()默认返回一个Promise对象;我们可以执行一个返回值,让下一次的then(),由这个返回值执行
    return p2;
}).then(res => {
    console.log(res);
    return p3;
}).then(res => {
    console.log(res);
});
  • then()默认返回一个Promise对象,我们可以执行一个返回值,让下一次的then(),由这个返回值执行
  • Promise将回调地狱变为链式编程
  • Promise对象封装:
import fs from 'fs';
//封装一个方法,可以返回一个Promise对象,传递哪个文件路径,就读取哪个文件
function getProObj(url){
    //返回一个Promise对象
    return new Promise((resolve,reject) => {
        fs.readFile(url,'utf8',(err,data) => {
            resolve(data);
        });
    });
};
//用封装函数的方法,解决回调地狱,就不用每次都手动创建Promise对象
getProObj('./txt/a.txt').then((res) => {
    console.log(res);
    //返回一个Promise对象,调用下一个then()
    return getProObj('./txt/b.txt');
}).then((res) => {
    console.log(res);
    //返回一个Promise对象,调用下一个then()
    return getProObj('./txt/c.txt');
}).then((res) => {
    console.log(res);
});
  • 实际工作中,会有好多的框架,直接返回Promise对象,例如axios.js

4.2then-fs模块

  • fs是内置模块/核心模块
  • then-fs是第三方模块,需要下载使用,支持Promise对象开发
  • 演示then-fs:
import fs from 'fs';
let p1 = fs.readFile('./txt/a.txt','utf8',() => {});
//fs.readFile()的返回值是undefined
console.log(p1);
  • 演示 then-fs模块,需要下载:
import thenFs from 'then-fs';
let p2 = thenFs.readFile('./txt/a.txt');
//thenFs.readFile()返回的是一个Promise对象
console.log(p2);
  • then-fs模块解决回调地狱:
import thenFs from 'then-fs';
thenFs.readFile('./txt/a.txt','utf8').then(res => {
    console.log(res);
    //返回一个Promise对象
    return thenFs.readFile('./txt/b.txt','utf8')
}).then(res => {
    console.log(res);
    //返回一个Promise对象
    return thenFs.readFile('./txt/c.txt','utf8')
}).then(res => {
    console.log(res);
});
  • 以后记住,尽量多的使用支持Promise对象开发的模块; axios.js then-fs mysql …

4.3async和await

4.3.1async关键字
  1. async 修饰的函数,总是返回一个 Promise 对象
  2. 函数内的返回值,将自动包装在** resolved 的 promise** 中
  3. 注意:用async修饰的函数,并不会真的变成异步函数;
  4. 代码:
async function fn(){
    return '哈哈哈';
};
//执行函数
let a = fn();
console.log(a);
a.then(res => {
    console.log(res);//then()里面的代码,会以异步形式最后执行
})
console.log('我是最后一行');
4.3.2await关键字
  1. await只能出现在异步函数
  2. await能停止代码执行,让后面的同步代码,先执行
  3. await后面跟随的是一个promise对象
  4. await返回的是: Promise对象中的then()中的回调函数中的参数res
  5. 代码:
//定义一个异步函数,用于获取一个Promise对象用
async function getProObj(){
    return '哈哈哈'
};
//定义一个方法,要求是异步的
async function fn(){
    //await可以停止程序,把Promise对象中then()的res对象返回
    let a = await getProObj();//getProObj()可以返回一个promise对象
    console.log(a);
    console.log('我是函数中的最后一行代码');
};
fn();
console.log('我是最后一行');
4.3.3async和await解决回调函数
  • 代码:
//我们需要使用then-fs模块,再配合async和await,就方便多了
//导入then-fs模块
import thenFs from 'then-fs';
//定义一个异步函数,因为await必须出现在异步函数中
async function fn(){
    let t1 = await thenFs.readFile('./txt/a.txt','utf8');
    console.log(t1);
    let t2 = await thenFs.readFile('./txt/b.txt','utf8');
    console.log(t2);
    let t3 = await thenFs.readFile('./txt/c.txt','utf8');
    console.log(t3);
};
fn();
  • try,尝试执行某些代码
  • try中出现异常的对象,会赋值到e这个形参中
  • **try…catch…**可以处理异步的异常

5.宏任务、微任务、事件循环

  • JavaScript是单线程的,也就是说,同一个时刻,JavaScript只能执行一个任务,其他任务只能等待
  • 同步任务:同步任务不需要进行等待可立即看到执行结果,比如console
  • 异步任务:异步任务需要等待一定的时候才能看到结果,比如setTimeout、网络请求
  • 执行机制:
    1. js代码开始执行后,主线程执行栈中会把任务分为两类
    2. 一类是同步任务, 一类是异步任务; 主线程执行栈优先执行同步任务
    3. 异步任务会被放入特定的处理程序中,满足条件后,被放到消息(任务/事件)队列中
    4. 主线程执行栈中所有的同步任务执行完毕之后,通过事件循环去消息(任务/事件)队列中
    5. 挑选优先满足条件的程序,放入主线程执行栈中执行。事件循环,周而复始,一直执行
  • 面试题:
//异步 - 宏任务
setTimeout(() => {
    //执行后 回调一个宏事件
    console.log('1')
}, 0);
//同步
console.log('2');
//同步
new Promise((resolve) => {
    console.log('3');
    resolve()
}).then(() => {
    //异步 - 微任务
    console.log('4');
}).then(()=>{
    //异步 - 微任务
    console.log('5')
});
//同步
console.log('6')
//输出2、3、6、4、5、1
//总结:Promise对象的then()方法要比其他的异步先执行  
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值