1. 代码的执行流程
代码的执行流程分为同步与异步。
2. 什么样子的是宏任务?
1. setTimeout 和 setInterval 定时器: 没有写时间(传参的),代表下一帧执行,如果没有其他任务1ms后执行。
// 没有写时间(传参的),代表下一帧执行,如果没有其他任务1ms执行。
setTimeout(() => {
})
-------------------------------
setInterval(()=>{
})
2. setImmediate的使用和setTimeout类似的,但是在间隔一段时间后执行,闲时执行。闲时执行:是指cpu不繁忙的时候。
setImmediate(()=>{
})
注意!!!
如果没有大量运行代码时,setImmediate 比 setTimeout 和 setInterval 先执行。
如果运行当中cpu被占用时,setTimeout 和 setInterval 比 setImmediate 先执行。
3. 什么样子的是微任务?
nextTick 等同于Promise.resolve.then(()=>{})。是异步执行。
// 等同于Promise.resolve.then(()=>{})
process.nextTick(()=>{
})
3.1 案例1分析:
console.log("a");//同步
new Promise(function (resolve, reject) {
resolve();
console.log("b");//同步
}).then(function () {//异步
console.log("c");
})
setTimeout(() => {//异步
console.log("d");
})
console.log("e");//同步
为什么执行流程是这样的呢?
因为遇到宏任务将开辟一个新的任务栈,将这个宏任务放在新任务栈的最顶端。遇到微任务,将放在当前任务栈的最下面。
所以执行结果是:a ----> b ----> e ----> c ----> d
3.2 案例2分析:如果遇到微任务与宏任务遇到一起了是怎么执行的?
// 如果遇到微任务与宏任务遇到一起了是怎么执行的?
new Promise(function (resolve, reject) {
resolve();
}).then(function () {//异步微任务
setTimeout(() => {//异步宏任务
console.log("a");
})
})
setTimeout(() => {//异步宏任务
new Promise(function (resolve, reject) {
resolve();
}).then(function () {//异步微任务
console.log("b");
})
})
所以执行结果是: b ----> a
3.3 案例3分析:
async function fn1() {
console.log("a");
await Promise.resolve();//异步微任务
console.log("b");
}
function fn2() {//同步
console.log("c");
}
function init() {//同步
fn1();
fn2();
}
init();
所以执行结果是: a ----> c ----> b
3.4 案例4分析:比较几种写法任务的执行速度
写法一:微任务密集性高,速度快。
new Promise(function (resolve, reject) {
resolve();
}).then(function () {//异步微任务
console.log("a1");
}).then(function () {//异步微任务
console.log("b1");
}).then(function () {//异步微任务
console.log("c1");
}).then(function () {//异步微任务
console.log("d1");
}).then(function () {//异步微任务
console.log("e1");
}).then(function () {//异步微任务
console.log("f1");
}).then(function () {//异步微任务
console.log("g1");
}).then(function () {//异步微任务
console.log("h1");
})
写法二:微任务密集性中等,速度中等。
// 中
new Promise(function (resolve, reject) {
resolve();
}).then(function () {//异步微任务
console.log("a2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("b2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("c2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("d2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("e2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("f2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("g2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("h2");
return new Promise(function (resolve, reject) {
resolve();
})
})
写法三:微任务密集性低,速度低。
new Promise(function (resolve, reject) {
resolve(new Promise(function (resolve1, reject1) {
resolve1();
}))
}).then(function () {
console.log("a3");
})
写法四:微任务密集性低,速度低。等同于写法三。
Promise.resolve().then(function () {
console.log("a4");
Promise.resolve().then(function () {
console.log("b4");
Promise.resolve().then(function () {
console.log("c4");
Promise.resolve().then(function () {
console.log("d4");
Promise.resolve().then(function () {
console.log("e4");
Promise.resolve().then(function () {
console.log("f4");
Promise.resolve().then(function () {
console.log("g4");
Promise.resolve().then(function () {
console.log("h4");
});
});
});
});
});
});
});
});
1. 写法一与写法二作比较:
// 写法一:密集性 快
new Promise(function (resolve, reject) {
resolve();
}).then(function () {//异步微任务
console.log("a1");
}).then(function () {//异步微任务
console.log("b1");
}).then(function () {//异步微任务
console.log("c1");
}).then(function () {//异步微任务
console.log("d1");
}).then(function () {//异步微任务
console.log("e1");
}).then(function () {//异步微任务
console.log("f1");
}).then(function () {//异步微任务
console.log("g1");
}).then(function () {//异步微任务
console.log("h1");
})
// 写法二:中
new Promise(function (resolve, reject) {
resolve();
}).then(function () {//异步微任务
console.log("a2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("b2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("c2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("d2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("e2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("f2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("g2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("h2");
return new Promise(function (resolve, reject) {
resolve();
})
})
写法一与写法二作比较:
除了第一次的执行,后面的代码执行,写法一都会比写法二多执行两次。
原因:因为写法二需要接收到上一个then执行的结果才能继续向后执行。
2. 写法一与写法三作比较:
//写法一:快
new Promise(function (resolve, reject) {
resolve();
}).then(function () {//异步微任务
console.log("a1");
}).then(function () {//异步微任务
console.log("b1");
}).then(function () {//异步微任务
console.log("c1");
}).then(function () {//异步微任务
console.log("d1");
}).then(function () {//异步微任务
console.log("e1");
}).then(function () {//异步微任务
console.log("f1");
}).then(function () {//异步微任务
console.log("g1");
}).then(function () {//异步微任务
console.log("h1");
})
//写法三: 慢
new Promise(function (resolve, reject) {
resolve(new Promise(function (resolve1, reject1) {
resolve1();
}))
}).then(function () {
console.log("a3");
})
写法一与写法三作比较:写法一执行速度更快。
写法二与写法三作比较:
// 写法二: 中
new Promise(function (resolve, reject) {
resolve();
}).then(function () {//异步微任务
console.log("a2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("b2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("c2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("d2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("e2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("f2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("g2");
return new Promise(function (resolve, reject) {
resolve();
})
}).then(function () {//异步微任务
console.log("h2");
return new Promise(function (resolve, reject) {
resolve();
})
})
//写法三: 慢
new Promise(function (resolve, reject) {
resolve(new Promise(function (resolve1, reject1) {
resolve1();
}))
}).then(function () {
console.log("a3");
})
写法二与写法三作比较:写法二执行速度快一点。
4. node.js的基础知识
1. 什么是node.js?
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,它使得 JavaScript 可以在服务器端运行。Node.js 使用事件驱动、非阻塞式 I/O 模型,使其轻量又高效。简单来说,Node.js 就是运行在服务端的 JavaScript,利用 JavaScript 在服务端进行编程。
2. node的版本:
- 1 是大版本 :代码产生大的变化。
- 2 是小版本 :代码迭代增加新的内容。
- 3 是微版本 :修复了代码中bug。
偶数版本为稳定版 (0.6.x ,0.8.x ,0.10.x)
奇数版本为非稳定版(0.7.x ,0.9.x ,0.11.x)
3. node.js的问题:
- 以前版本安装的很多全局的工具包需要重新安装。
- 无法回滚到之前的版本。
- 无法在多个版本之间切换(很多时候我们要使用特定版本)。
4. node.js 可以做什么?
-
Web 开发:使用 Express 框架快速搭建 Web 应用。
-
实时通信:使用 Socket.io 实现 Web 聊天室等实时通信应用。
-
Web 爬虫:使用 Cheerio 和 Request 库进行 Web 爬虫开发。
-
REST API:使用 Restify 框架开发 RESTful 服务。
-
博客系统:使用 Hexo 框架搭建静态博客。
-
论坛系统:使用 Node Club 框架搭建社区论坛。
5. node版本切换工具nvm
nvm下载网址: https://github.com/coreybutler/nvm-windows/releases
1. nvm -v: 查看nvm的版本号。
2. nvm ls :查看所有已经安装的node版本。
3. nvm install v版本 :安装指定的node版本。
nvm install v12.16.3
nvm install v10.12
4. nvm uninstall v版本:卸载安装的版本。
nvm uninstall v12.16.3
nvm uninstall v10.12
5. nvm use 版本:使用某个node版本。
nvm use v10.12
6. node执行:
node main 1 2
console.log(process.argv.slice(2))
process.argv
7. 尝试使用浏览器完成调试node代码:
node --inspect a.js
打开地址浏览器地址 chrome://inspect/
添加地址然后重新打开
node --inspect --inspect-brk a.js
8. node进程管理工具:
nodemon
supervisor
forever
pm2
npm i nodemon -g
nodemon a
或者
npx nodemon a
6. node的平台的包管理器npm
npm 是 Node JavaScript 平台的包管理器。它将模块放置到位,以便 node 可以找到它们,并智能地管理依赖冲突。它具有极强的可配置性,可以支持各种用例。最常见的是,您使用它来安装、卸载、更新、查看、搜索、发布和开发 node 程序。运行 npm help
以获取可用命令的列表。
npm的背后,是基于couchdb的一个数据库,详细记录了每个包的信息,包括作者、版本、依赖、授权信息等。它的一个很重要的作用就是:将开发者从繁琐的包管理工作(版本、依赖等)中解放出来,更加专注于功能的开发。
6.1 常用命令
- npm init -y : 自动生成默认的包配置文件package.json。如果没有写-y就需要你自己一步一步的填写配置信息。
- npm -v :查看npm版本。
下载包的命令:
- npm install 包名:下载指定的包。缩写npm i 包名 。
- npm install 包名@latest :下载最新版本的包。缩写npm i 包名@latest。
- npm install 包名@版本 :下载指定版本的包。缩写npm i 包名@版本。
全局安装命令:
- npm i 包名 -g :全局安装 ,命令行插件可以这么安装。
- npm i nrm -g :全局安装 nrm包 ,nrm包的作用是转换npm的下载地址镜像。
- nrm ls :查看所有镜像地址。
- nrm test 镜像地址(镜像名):测试镜像地址的速度。
- nrm use 镜像地址(镜像名) :使用某个镜像地址。
- npm i nodemon -g :全局安装nodemon包。nodemon包的作用是实时自动执行程序。nodemon 文件名.js :执行该文件。
- npm i http-server -g :全局安装http-server包。http-server创建一个web服务。
- npm i webpack -g :全局安装webpack打包工具。
6.2 依赖包分类
1. 项目中用到插件主要分两种,一种项目依赖,一种是开发依赖。
- dependencies项目依赖:比如项目中需要使用vue或者lodash,项目上线后,vue和lodash都需要一起放在线上,否则无法运行。
- devDependencies开发依赖:项目中如果需要打包、测试、创建临时服务器等操作时,下载的webpack等都是本地开发时需要,但是线上运行时不需要,这种包就叫做开发依赖。
安装到项目依赖中3种写法:
- npm i 包名 --save
- npm i 包名 -S
- npm i 包名
安装到开发依赖中2种写法:
npm i 包名 --save-dev
npm i 包名 -D
同时下载多个包的命令:
npm i 包名1 包名2 包名3 -S
6.3 其它npm命令详解
根据配置文件下载包:
- npm i :根据package.json文件中dependencies和devDependencies下载更新里面的所有内容。
- npm update :作用和npm i 是一样的。
查看命令:
- npm view 包名 versions :查找指定包线上发布所有版本。
- npm view 包名 :查找指定包的信息。
- npm ls :查看所有安装的包列表。
- npm ls 包名 :查看指定包名的依赖。
清除缓存命令:不支持断点续传和多点下载。
- npm cache clean --force
- npm cache verify
卸载包命令·:
- npm uninstall 包名
- npm uninstall 包名 -g
- npm uninstall 包名 -S
- npm uninstall 包名 -D
配置下载镜像地址命令:
- npm config set registry https://registry.npmjs.org/
查看npm的代理服务命令:
- npm config get proxy