先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Web前端全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024c (备注前端)
正文
服务器端需要根据不同的请求地址,作出不同的响应
// 创建一个web服务器
const server = http.createServer((req, res) => {
//最基本的使用方式
if (req.url === ‘/login’) {
res.end(“欢迎回来~”);
} else if (req.url === ‘/users’) {
res.end(“用户列表~”);
} else {
res.end(“错误请求, 检查~”);
}
那么如果用户发送的地址中还携带一些额外的参数呢?
比如:http://localhost:8000/login?name=why&password=123
这个时候,url的值是 /login?name=why&password=123
我们如何对它进行解析呢?使用内置模块url
=========================================================================
我们来看一下 req 里面能够使用的东西。
- 最重要的是
req.url
属性,表示用户的请求URL 地址。所有路由设计,都是通过req.url
来实现的。
const http = require(‘http’);
http.createServer(function(request, response) {
console.log(request.url);
//发送响应头
response.writeHead(200, { ‘Content-Type’: ‘text/html;charset=“UTF-8”’ });
//表示给我们页面上面输出一句话并且结束响应
response.write(‘你好 Nodejs’);
response.end(‘
你好 Nodejs
’);}).listen(3000); //监听端口
这里注意一下输出是在 Nodejs 控制台输出,而不是在浏览器上输出。因为输出是在服务端,浏览器是客户端
-
我们比较关心的不是拿到 URL,而是识别这个 URL。
-
识别 URL,下面的 url 模块
旧版本 Node 的 url 用法如下:
| url模块的使用 | 说明 |
| — | — |
| url.parse() | 解析 url(第二个参数为true,可以将 query 里面的数据转换为对象) |
| url.format(urlObject) | 是上面 url.parse() 操作的逆向操作 |
| url.resolve(from,to) | 添加或者替换地址 |
const url = require(‘url’);
var api = ‘http://www.itying.com?name=zhangsan&age=20’;
//console.log(url.parse(api, true));
var getValue = url.parse(api, true).query;
console.log(getValue);
// ES6中模板字符串写法
console.log(姓名:${getValue.name}--年龄:${getValue.age}
);
新版本 Node 的 url 用法如下:
-
new URL(input,[,base])
: -
input
类型:String,要解析的绝对或相对的输入网址。如果 input 是相对的,则需要 base。如果 input 是绝对的,则忽略 base。
const myURL = new URL(‘/foo’, ‘https://example.org/’);
// https://example.org/foo
const url = require(‘url’);
const myURL = new URL(
“http://localhost:3000/p/a/t/h?name=zhangsan&age=20#hash”);
console.log(myURL);
searchParams 可以获取到 url 参数的 value
const myURL = new URL(‘https://example.org/?abc=123’);
console.log(myURL.searchParams.get(‘abc’));
// 打印 123
myURL.searchParams.append(‘abc’, ‘xyz’);
console.log(myURL.href);
// 打印 https://example.org/?abc=123&abc=xyz
myURL.searchParams.delete(‘abc’);
myURL.searchParams.set(‘a’, ‘b’);
console.log(myURL.href);
// 打印 https://example.org/?a=b
============================================================================
supervisor 会不停的watch 你应用下面的所有文件,发现有文件被修改,就重新载入程序文件这样就实现了部署,修改了程序文件后马上就能看到变更后的结果。麻麻再也不用担心我的重启nodejs 了
- 首先安装 supervisor(在cmd控制台输入下方代码)
npm install -g supervisor
- 使用 supervisor 代替 node 命令启动应用
supervisor app.js
-
nodemon 和 supervisor 的功能一样,两者安装一个即可
-
使用
npm install -g nodemon
下载它(-g 是全局安装) -
在命令行工具中用
nodemon
命令替代node
命令执行文件
nodemon app.js
==========================================================================
fs:file system ,文件操作系统,是系统模块,直接引入即可使用.
文件系统的API非常的多,我们不可能,也没必要一个个去学习,更多的是使用是时候去查对应的API
fs.stat :检测是文件还是目录:
-
第一个参数是 path :路径
-
第二个参数是 callback:回调函数
const fs = require(‘fs’);
// 1. fs.stat 检测是文件还是目录
fs.stat(‘./html’,(err,data)=>{
if(err){
console.log(err);
return;
}
console.log(是文件:${data.isFile()}
);
console.log(是目录:${data.isDirectory()}
);
})
fs.mkdir(): 创建目录
-
第一个参数 path:将要创建的目录路径
-
第二个参数 mode:目录权限(读写权限),默认为777
-
第三个参数 callback:回调函数,传递异常参数 err
fs.mkdir(‘./css’,(err)=>{
if(err){
console.log(err);
return;
}
console.log(‘创建成功’);
})
fs.writeFile :创建写入文件
-
第一个参数 filename:文件名称
-
第二个参数 data:将要写入的内容,可以使用字符串或 buffer 数据
-
第三个参数 options:option 数组对象,包含
-
encoding :可选值,默认为 ‘utf8’,当 data 使用 buffer 时,该值应该为 ignored
-
mode:文件读写权限,默认为 438
-
flag :默认为 ‘w’
-
第四个参数 callback:回调函数,传递一个异常参数 err
fs.writeFile(‘./html/index.html’,‘你好nodejs’,(err)=>{
if(err){
console.log(err);
return;
}
console.log(‘创建写入文件成功’);
})
fs.writeFile(‘./html/index.html’,‘你好nodejs 哈哈’,(err)=>{
if(err){
console.log(err);
return;
}
console.log(‘创建写入文件成功’);
})
注意:如果没有这个文件,则会新建一个文件,如果已经有这个文件,那么会覆盖这个文件里面的内容
fs.appendFile 追加文件
-
第一个参数 path:将要追加的文件路径
-
第二个参数 data:要追加的文件内容
-
第三个参数callback:回调函数,传递一个异常参数 err
fs.appendFile(‘./css/base.css’,‘body{color:red}’,(err)=>{
if(err){
console.log(err);
return;
}
console.log(‘appendFile 成功’);
})
fs.appendFile(‘./css/base.css’,‘h3{color:red}\n’,(err)=>{
if(err){
console.log(err);
return;
}
console.log(‘appendFile 成功’);
})
注意:如果这个文件不存在,则会新建文件,如果文件已经存在,则会在文件内容后面追加内容
fs.readFile 读取文件:
-
第一个参数路径 path:想要读取的文件的路径
-
第二个参数callback:回调函数,传递一个异常参数 err 和读取的文件数据 data,data类型是 Buffer
fs.readFile(‘./html/index.html’,(err,data)=>{
if(err){
console.log(err);
return;
}
console.log(data);
console.log(data.toString()); //把Buffer 转化成string类型
})
fs.readFile(‘./aaa/index.html’,(err,data)=>{
if(err){
console.log(err);
return;
}
console.log(data);
console.log(data.toString()); //把Buffer 转化成string类型
})
fs.readdir 读取目录:
fs.readdir(‘./html’,(err,data)=>{
if(err){
console.log(err);
return;
}
console.log(data);
})
fs.rename :重命名,功能:1、表示重命名 2、移动文件
fs.rename(‘./css/aaa.css’,‘./css/index.css’,(err)=>{
if(err){
console.log(err);
return;
}
console.log(‘重命名成功’);
})
fs.rename(‘./css/index.css’,‘./html/index.css’,(err)=>{
if(err){
console.log(err);
return;
}
console.log(‘移动文件成功’);
})
fs.rmdir 删除目录
fs.rmdir(‘./aaaa’,(err)=>{
if(err){
console.log(err);
return;
}
console.log(‘删除目录成功’);
})
注意:要删除目录之前需要先删除目录下的所有文件
fs.unlink 删除文件
fs.unlink(‘./aaaa/index.html’,(err)=>{
if(err){
console.log(err);
return;
}
console.log(‘删除文件成功’);
})
fs.createReadStream: 从文件流中读取数据
const fs = require(‘fs’);
// 以流的方式读取 data 目录下的 aaa.txt
var ReadStream = fs.createReadStream(“./data/aaa.txt”);
let count = 0;
var str = ‘’;
// 通过 on 方法监听 data,表示我们读取到了这个数据
ReadStream.on(‘data’, (data) => {
str += data;
count++;
})
// 通过 on 方法监听 end,表示我们读取完了这个数据
ReadStream.on(‘end’, () => {
console.log(str);
console.log(count);
})
// 通过 on 方法监听 error,表示读取过程中的错误信息
ReadStream.on(‘error’, (err) => {
console.log(err);
})
fs.createWriteStream:写入文件
const fs = require(‘fs’);
for(var i=0;i<500;i++){
str +=‘我是从数据库获取的数据,我要保存起来’
}
// 以流的方式写到 data目录下的 output.txt
var writeStream = fs.createWriteStream(‘/data/output.txt’);
writeStream.write(str);
//标记写入完成
writeStream.end();
writeStream.on(‘finish’,()=>{
console.log(‘写入完成’);
})
管道提供了一个输出流到输入流的机制。通常我们用于从一个流中获取数据并将数据传递到另外一个流中。
const fs = require(‘fs’);
// 创建一个可读流
var readerStream = fs.createReadStream(‘input.txt’);
// 创建一个可写流
var readStream = fs.createReadStream(‘output.txt’)
// 管道读写操作
// 读取 input.txt 文件内容,并将内容写入到 output.txt 文件中
readStream.pipi(writeStream);
console.log(‘程序执行完毕。’);
=========================================================================
- 同步API可以从返回值中拿到API执行的结果, 但是异步API是不可以的
// 同步
function sum (n1, n2) {
return n1 + n2;
}
const result = sum (10, 20); // 30
// 异步
function getMsg () {
setTimeout(function () {
return { msg: ‘Hello Node.js’ }
}, 2000);
// return undefined;
}
const msg = getMsg (); // undefined
- 同步API从上到下依次执行,前面代码会阻塞后面代码的执行
for (var i = 0; i < 100000; i++) {
console.log(i);
}
console.log(‘for循环后面的代码’);
- 异步API不会等待API执行完成后再向下执行代码
console.log(‘代码开始执行’);
setTimeout(() => { console.log(‘2秒后执行的代码’)}, 2000);
setTimeout(() => { console.log(‘"0秒"后执行的代码’)}, 0);
console.log(‘代码结束执行’);
//代码开始执行
//代码结束执行
//"0秒"后执行的代码
//2秒后执行的代码
同步API 放在同步代码执行区,异步API放在异步代码执行区,同时将异步API 所对应的回调函数放在回调函数队列,这个时候注意,同步代码执行区和回调函数队列两者里面的代码没有执行,当同步代码区里面的内容执行完毕,这个时候去异步代码区,发现第二个 setTimeout 执行完毕,则将其对应的回调函数放入同步代码区执行,再去异步代码区发现第一个 setTimeout 执行完毕,再将其对应的回调函数放入同步代码区执行。
自己定义函数让别人去调用。
回调函数视频讲解:https://www.bilibili.com/video/BV1UE411H71P?p=36
// getData函数定义
function getData (callback) {}
// getData函数调用
getData ( () => {});
getData 函数有一个形参 callback,传递的实参是一个函数,将一个函数作为另外一个函数的形参,则此形参就叫做回调函数。
function getData(callback) {
callback(‘123’); // 使用callback可以调用下面的匿名函数function,并给callback传递参数
//callback函数被调用了
}
// 调用函数
getData(function(n) {
console.log(‘callback函数被调用了’);
console.log(n);
// 123
})
- 我们可以调用 callback 回调函数将异步API执行的结果传递出来
function getMsg (callback) {
// 调用callback将异步API执行的结果传递出来
setTimeout(function () {
callback ({ msg: ‘Hello Node.js’ })
}, 2000);
}
getMsg (function (msg) {
console.log(msg);
// { msg: ‘Hello Node.js’ }
});
fs.readFile(‘./demo.txt’,(err,result) => {});
- 读取文件是需要时间的,文件读取的结果不能通过返回值的方式获取,需要通过回调函数。
var server = http.createServer();
server.on(‘request’,(req,res) => {});
- 事件监测也是异步API
如果异步API后面代码的执行依赖当前异步API的执行结果,但实际上后续代码在执行的时候异步API还没有返回结果,这个问题要怎么解决呢?
例如,我们需要依次读取A文件、B文件、C文件
const fs = require(‘fs’);
fs.readFile(‘./1.txt’,‘utf8’,(err,result1) => {
console.log(result1);
fs.readFile(‘./2.txt’,‘utf8’,(err,result2)=> {
console.log(result2);
fs.readFile(‘./3.txt’,‘utf8’,(err,result3)={
console.log(result3);
})
})
})
回调嵌套的情况就叫做 回调地狱
Promise 出现的目的是解决 Node.js 异步编程中回调地狱的问题。
实际上,Promise 本身是一个构造函数,我们要解决回调地狱的问题,需要先使用 new 运算符创建 Promise 实例,在创建 Promise 实例的过程中,需要传入一个匿名函数,在匿名函数中有两个参数。
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
if (true) {
resolve({name: ‘张三’})
}else {
reject(‘失败了’)
}
}, 2000);
});
promise.then(result => console.log(result) // {name: ‘张三’})
.catch(error => console.log(error); // 失败了)
例如,我们需要依次读取A文件、B文件、C文件
function p1() {
return new Promise((resolve,reject) => {
fs.readFile(‘./1.txt’,‘utf8’,(err,result) => {
resolve(result);
})
});
}
function p2() {
return new Promise((resolve,reject) => {
fs.readFile(‘./2.txt’,‘utf8’,(err,result) => {
resolve(result);
})
});
}
function p3() {
lreturn new Promise((resolve,reject) => {
fs.readFile(‘./3.txt’,‘utf8’,(err,result) => {
resolve(result);
})
});
}
p1().then((r1) => {
console.log(r1);
return p2(); //返回一个promise对象
})
.then((r2) => {
console.log(r2);
return p3();
})
.then((r3) => {
console.log(r3);
return p3;
})
异步函数是异步编程语法的终极解决方案,它可以让我们将异步代码写成同步的形式,让代码不再有回调函数嵌套,使代码变得清晰明了。
const fn = async () => {};
async function fn () {}
6.5.1、async关键字
-
普通函数定义前加async关键字 普通函数变成异步函数
-
异步函数默认返回promise对象
-
在异步函数内部使用return关键字进行结果返回 结果会被包裹在promise对象中 return关键字代替了resolve方法
-
在异步函数内部使用throw关键字抛出程序异常
-
调用异步函数再链式调用then方法获取异步函数执行结果
-
调用异步函数再链式调用catch方法获取异步函数执行的错误信息
// 1. 普通函数定义前加async关键字,普通函数变成异步函数
// 2. 异步函数默认的返回值是promise 对象
async function fn() {
throw ‘发生了一些错误’;
return 123;
}
fn ().then(function(data) {
console.log(data); //123
}).catch(function (err) {
console.log(err); //发生了一些错误
})
6.5.2、await关键字
-
await关键字只能出现在异步函数中
-
await promise await后面只能写promise对象 写其他类型的API是不可以的
-
await关键字是暂停异步函数向下执行 直到promise返回结果
async function p1() {
return ‘p1’; // 返回的是 promise 对象
}
async function p2() {
return ‘p2’;
}
async function p3() {
return ‘p3’;
}
async function run() {
await p1();
await p2();
await p3();
}
run();
简单理解:
-
async 是让方法变成异步
-
await 是等待异步方法执行完成
在浏览器中全局对象是 window,在 Node 中全局对象是 global。
Node 中全局对象有以下方法,可以在任何地方使用,global 可以省略
-
console.log() 在控制台输出、
-
setTimeout() 设置超时定时器
-
clearTimeout() 清除超时定时器
-
setInterval() 设置间歇定时器
-
clearInterval() 清除间歇定时器
注意:Node中不存在 BOM、DOM,所以全局对象是 global。但是在 DOM、BOM 中也有这些方法,只是全局对象是 window。
6.7.1、回调函数获取
// 回调函数 获取异步方法里面的数据
function getData(callbck){
setTimeout(function(){
var name=‘张三’;
callbck(name);
},1000);
}
//外部获取异步方法里面的数据
getData(function(data){
console.log(data+‘111’);
})
6.7.2、Promise获取
//Promise来处理异步 resolve 成功的回调函数 reject失败的回调函数
var p=new Promise(function(resolve,reject){
setTimeout(function(){
var name=‘张三’;
if(Math.random()<0.7){
resolve(name);
}else{
总结
大厂面试问深度,小厂面试问广度,如果有同学想进大厂深造一定要有一个方向精通的惊艳到面试官,还要平时遇到问题后思考一下问题的本质,找方法解决是一个方面,看到问题本质是另一个方面。还有大家一定要有目标,我在很久之前就想着以后一定要去大厂,然后默默努力,每天看一些大佬们的文章,总是觉得只有再学深入一点才有机会,所以才有恒心一直学下去。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
async 是让方法变成异步
- await 是等待异步方法执行完成
在浏览器中全局对象是 window,在 Node 中全局对象是 global。
Node 中全局对象有以下方法,可以在任何地方使用,global 可以省略
-
console.log() 在控制台输出、
-
setTimeout() 设置超时定时器
-
clearTimeout() 清除超时定时器
-
setInterval() 设置间歇定时器
-
clearInterval() 清除间歇定时器
注意:Node中不存在 BOM、DOM,所以全局对象是 global。但是在 DOM、BOM 中也有这些方法,只是全局对象是 window。
6.7.1、回调函数获取
// 回调函数 获取异步方法里面的数据
function getData(callbck){
setTimeout(function(){
var name=‘张三’;
callbck(name);
},1000);
}
//外部获取异步方法里面的数据
getData(function(data){
console.log(data+‘111’);
})
6.7.2、Promise获取
//Promise来处理异步 resolve 成功的回调函数 reject失败的回调函数
var p=new Promise(function(resolve,reject){
setTimeout(function(){
var name=‘张三’;
if(Math.random()<0.7){
resolve(name);
}else{
总结
大厂面试问深度,小厂面试问广度,如果有同学想进大厂深造一定要有一个方向精通的惊艳到面试官,还要平时遇到问题后思考一下问题的本质,找方法解决是一个方面,看到问题本质是另一个方面。还有大家一定要有目标,我在很久之前就想着以后一定要去大厂,然后默默努力,每天看一些大佬们的文章,总是觉得只有再学深入一点才有机会,所以才有恒心一直学下去。
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注前端)
[外链图片转存中…(img-BbkQjuNQ-1713707073236)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!