async与await是Promise结合Generator函数的语法糖。
async和await可以分开,一般不会分开。
async必须和函数一块使用,会返回一个Promise实例对象。
async function getData() {
return 10;
}
console.log(getData());
getData()
.then((value) => {
console.log(value);
})
.catch((err) => {
console.log("err", err);
});
返回值为ES5普通类型—>状态fulfilled,值为返回值。
async function getData() {
return 10;
}
console.log(getData());
返回值默认是状态fulfilled,值为undefined。
async function getData() {
}
console.log(getData());
返回值为Promise实例对象
如果函数语句出错,会返回一个Promise实例对象。状态为rejected,值为错误原因对象。
但是控制台依旧会报错,要使用try和catch来捕获
async function getData() {
console.log(a);
}
console.log(getData());
async function getData() {
try {
console.log(a);
} catch (err) {
console.log(err);
}
return 10;
}
console.log(getData());
async function getData() {
console.log(a);
return 10;
}
getData()
.then((value) => {
console.log(value);
})
.catch((err) => {
console.log("err", err);
});
async的提出就是为了结合await使用
await后面可以跟普通值,默认会转化为一个Promise实例对象,状态为fulfilled,值为普通值。
async function getData() {
console.log("111");
const theNumber = 5;
let res1 = await theNumber; //此时theNumber会转化成一个状态为fulfilled,值为5的Promise实例对象,之后变成微任务交由await解析,await解析为结果5,赋值给res1。
console.log(res1);
}
getData();
Promise实例对象里面一般是异步任务。
let thePromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(100);
}, 1000);
console.log("111");
});
async function getData() {
console.log("222");
let res1 = await thePromise; //此时等待Promise实例对象thePromise转化成一个状态为fulfilled,值为100。之后交由await解析,await解析为结果100,赋值给res1。
console.log(res1);
}
getData();
console.log("333");
await同一句代码后面及上方都被认为是同步任务,以普通同步代码的方式在执行。但await同一行代码前面及下方都是异步任务。
let thePromise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(100);
}, 1000);
console.log("111");
});
async function getData() {
console.log("222");
let res1 = await thePromise;
console.log(res1);
}
getData();
console.log("333");
//"111"
//"222"//await同一句代码后面及上方都被认为是同步任务
//"333"
//100 //await同一行代码前面及下方都是异步任务。
await 必须等待同一句代码后面的任务成功完成,才能执行下方的代码
await 如果同一句代码后面的任务是失败的,下方的代码将不执行
let p = new Promise((resolve, reject) => {
console.log(a);
});
p.then((value) => {
console.log(value);
}).catch((err) => {
console.log("err", err);
});
async function getData() {
console.log(a);
return 10;
}
getData().then((value) => {
console.log(value);
}).catch((err) => {
console.log("err", err);
});
所以await一般配合try-catch来使用
async function getData() {
try {
console.log(a);
} catch (err) {
console.log(err);
}
return 10;
}
const get = function get(url, callback) {
let xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
let data = JSON.parse(xhr.response);
callback(data);
}
};
xhr.send();
};
function fn1() {
return new Promise((resolve, reject) => {
get("./data.json", function (data) {
resolve(data);
});
});
}
function fn2() {
return new Promise((resolve, reject) => {
get("./data.json", function (data) {
reject(data);
});
});
}
function fn3() {
return new Promise((resolve, reject) => {
get("./data.json", function (data) {
resolve(data);
});
});
}
//同步写法解决异步请求
async function getData() {
try {
let res1 = await fn1();
let res2 = await fn2();
let res3 = await fn3();
console.log(res1, res2, res3);
} catch (err) {
console.log("有失败的结果,执行中断了", err);
}
// console.log("111")
}
getData();
async function getData1() {
try {
let res1 = await fn1();
} catch (err) {
console.log("有失败的结果,执行中断1", err);
}
try {
let res2 = await fn2();
} catch (err) {
console.log("有失败的结果,执行中断2", err);
}
try {
let res3 = await fn3();
console.log(res1, res2, res3);
} catch (err) {
console.log("有失败的结果,执行中断3", err);
}
// console.log("111")
}
getData1()
//等价于
fn1().then(value=>{
console.log(value);
return fn2()
}).then(value=>{
console.log(value);
return fn3()
}).then(value=>{
console.log(value);
}).catch(err=>{
console.log(err);
})
await的结果值是它后方状态为fulfilled的Promise实例对象的结果值。
async可以没有await,await必须先有async。
同步写法解决异步任务
const get = function get(url, callback) {
let xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
let data = JSON.parse(xhr.response);
callback(data);
}
};
xhr.send();
};
function fn1() {
return new Promise((resolve, reject) => {
get("./data.json", function (data) {
resolve(data);
});
});
}
function fn2() {
return new Promise((resolve, reject) => {
get("./data.json", function (data) {
reject(data);
});
});
}
function fn3() {
return new Promise((resolve, reject) => {
get("./data.json", function (data) {
resolve(data);
});
});
}
//同步写法解决异步请求
// async function getData() {
// try {
// let res1 = await fn1();
// let res2 = await fn2();
// let res3 = await fn3();
// console.log(res1, res2, res3);
// } catch (err) {
// console.log("有失败的结果,执行中断了", err);
// }
// // console.log("111")
// }
// getData()
async function getData() {
let res1 = await fn1();
let res2 = await fn2();
let res3 = await fn3();
console.log(res1, res2, res3);
// console.log("111")
}
getData()
./data.json
[
{
"name": "前端开发基础",
"open": true,
"children": [
{
"name": "HTML5核心知识",
"children": [
{
"name": "新增语义化标签"
},
{
"name": "表单元素新特性"
},
{
"name": "音视屏处理"
},
{
"name": "canvas和webGL"
},
{
"name": "新增JS中的API"
}
]
},
{
"name": "CSS3核心知识",
"children": [
{
"name": "新增选择器"
},
{
"name": "字体图标"
},
{
"name": "常用的样式属性"
},
{
"name": "背景的处理"
},
{
"name": "transform变形"
},
{
"name": "CSS3动画",
"children": [
{
"name": "transition过度动画"
},
{
"name": "animation帧动画"
},
{
"name": "3D动画的处理"
}
]
},
{
"name": "新盒子模型属性",
"children": [
{
"name": "flex弹性盒子模型"
},
{
"name": "box-sizing新盒子模型属性"
},
{
"name": "cloumns多列布局"
}
]
}
]
},
{
"name": "实战案例和布局技巧",
"children": [
{
"name": "实战案例练习",
"children": [
{
"name": "居中处理"
},
{
"name": "同行排列"
},
{
"name": "圣杯布局"
},
{
"name": "双飞翼布局"
},
{
"name": "滑动门"
},
{
"name": "面包屑导航"
}
]
},
{
"name": "响应式布局开发",
"children": [
{
"name": "viewport和dpi适配"
},
{
"name": "@media媒体查询"
},
{
"name": "rem等比缩放"
},
{
"name": "百分比布局"
}
]
}
]
}
]
},
{
"name": "前端开发核心",
"children": [
{
"name": "JS(ES6)核心",
"children": [
{
"name": "基础知识"
},
{
"name": "闭包作用域及堆栈内存"
},
{
"name": "面向对象和THIS处理"
},
{
"name": "同步异步(事件循环、微任务、宏任务)"
},
{
"name": "DOM事件和事件委托"
},
{
"name": "设计模式"
}
]
},
{
"name": "AJAX前后端交互",
"children": [
{
"name": "AJAX基础知识"
},
{
"name": "跨域策略请求"
},
{
"name": "TCP协议相关基础知识"
},
{
"name": "性能和安全的初步优化"
},
{
"name": "常用的AJAX库和插件"
}
]
},
{
"name": "底层原理和高阶JS函数",
"children": [
{
"name": "函数柯里化"
},
{
"name": "compos函数"
},
{
"name": "惰性思想"
},
{
"name": "组件插件封装"
},
{
"name": "底层源码解读"
}
]
}
]
},
{
"name": "前端工程化",
"children": [
{
"name": "VUE全家桶",
"children": [
{
"name": "基础知识"
},
{
"name": "MVVM实现原理"
},
{
"name": "路由处理"
},
{
"name": "vuex公共状态管理"
},
{
"name": "element-ui组件应用和二次封装"
}
]
},
{
"name": "REACT全家桶",
"children": [
{
"name": "基础知识"
},
{
"name": "MVC实现原理"
},
{
"name": "DOM DIFF"
},
{
"name": "Virtual DOM"
},
{
"name": "路由处理"
},
{
"name": "公共状态管理",
"children": [
{
"name": "REACT-REDUX、DAVS/SAGA等"
},
{
"name": "compos函数"
},
{
"name": "惰性思想"
},
{
"name": "组件插件封装"
},
{
"name": "底层源码解读"
}
]
},
{
"name": "高阶租价"
},
{
"name": "antd组件应用和二次封装"
}
]
},
{
"name": "底层原理和高阶JS函数",
"children": [
{
"name": "函数柯里化"
},
{
"name": "compos函数"
},
{
"name": "惰性思想"
},
{
"name": "组件插件封装"
},
{
"name": "底层源码解读"
}
]
},
{
"name": "工程化开发部署",
"children": [
{
"name": "webpack"
},
{
"name": "git"
},
{
"name": "linux"
}
]
}
]
},
{
"name": "前端开发热门点",
"children": [
{
"name": "TypeScript"
},
{
"name": "flutter"
},
{
"name": "react native"
},
{
"name": "小程序"
},
{
"name": "性能和安全的优化"
}
]
}
]
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>zTree树形结构菜单title>
<style>
.container {
box-sizing: border-box;
margin: 20px auto;
padding: 10px;
width: 600px;
border: 1px dashed #aaa;
-webkit-user-select: none;
user-select: none;
}
.level {
display: none;
font-size: 14px;
margin-left: 10px;
/* transition: height .3s linear 0s;
overflow: hidden; */
}
.level.level0 {
display: block;
margin-left: 0;
}
.level li {
position: relative;
padding-left: 15px;
line-height: 30px;
}
.level li .icon {
position: absolute;
left: 0;
top: 9px;
box-sizing: border-box;
width: 12px;
height: 12px;
line-height: 8px;
text-align: center;
border: 1px solid #aaa;
background: #eee;
cursor: pointer;
}
.level li .icon:after {
display: block;
content: "+";
font-size: 12px;
font-style: normal;
}
.level li .icon.open:after {
content: "-";
}
.level li .title {
color: #000;
}
style>
head>
<body>
<div class="container">
<ul class="level level0" id="zTree">
<li>
<a href="javascript:;" class="title">第一级第一项a>
<em class="icon open">em>
<ul class="level" style="display: block">
<li>
<a href="javascript:;" class="title">第二级第一项a>
li>
ul>
li>
<li>
<a href="javascript:;" class="title">第一级第二项a>
li>
<li>
<a href="javascript:;" class="title">第一级第三项a>
li>
ul>
div>
body>
html>
<script>
(function () {
let zTree = document.getElementById("zTree");
//事件委托--功能
zTree.onclick = function (e) {
let tar = e.target;
//点击元素的相邻兄弟下一个ul
let ulbox = tar.nextElementSibling;
if (tar.tagName === "EM") {
//点击展开和收缩按钮
//contains判断是否具有某个class
//有 open --->删除open ul隐藏
if (tar.classList.contains("open")) {
tar.classList.remove("open");
ulbox.style.display = "none";
} else {
//没有 open --->添加open ul显示
tar.classList.add("open");
ulbox.style.display = "block";
}
}
};
//"异步方式"获取数据
function getData() {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open("get", "./data.json");
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
let data = JSON.parse(xhr.response);
resolve(data);
}
};
xhr.send();
});
}
//获取数据
async function fn() {
let data = await getData();
let str = render(data);
zTree.innerHTML = str;
}
fn();
//循环渲染
function render(data) {
let str = "";
data.forEach((item) => {
let { name, children, open } = item;
str += `
${name}
${
children
? `${open ? "open" : ""}"> ${open ? "block" : "none"}
;"> ${render(children)} `
: ""
}
`;
});
return str;
}
//方法一:
// getData()
// .then((value) => {
// console.log(value);
// })
// .catch((err) => {
// console.log(err);
// });
//方法二:
// async function render() {
// try {
// let data = await getData();
// console.log(data);
// } catch (error) {}
// }
// render();
})();
script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>zTree树形结构菜单</title>
<!-- IMPORT CSS -->
<style>
.container {
box-sizing: border-box;
margin: 20px auto;
padding: 10px;
width: 600px;
border: 1px dashed #aaa;
-webkit-user-select: none;
user-select: none;
}
.container .level {
display: none;
font-size: 14px;
margin-left: 10px;
/* transition: height .3s linear 0s;
overflow: hidden; */
}
.container .level.level0 {
display: block;
margin-left: 0;
}
.container .level li,
.container .level .the-item {
position: relative;
padding-left: 15px;
line-height: 30px;
}
.container .level li .icon,
.container .level .the-item .icon {
position: absolute;
left: 0;
top: 9px;
box-sizing: border-box;
width: 12px;
height: 12px;
line-height: 8px;
text-align: center;
border: 1px solid #aaa;
background: #eee;
cursor: pointer;
}
.container .level li .icon:after,
.container .level .the-item .icon:after {
content: "+";
display: block;
font-size: 12px;
font-style: normal;
}
.container .level li .icon.open:after,
.container .level .the-item .icon.open:after {
content: "-";
}
.container .level li .title,
.container .level .the-item .title {
color: #000;
}
</style>
</head>
<body>
<div class="container">
<ul class="level level0" id="zTree">
<li class="the-item">
<a class="title" href="javascript:;">第一级第一项</a>
<em class="icon open"></em>
<ul class="level" style="display: block">
<li class="the-item">
<a href="javascript:;" class="title">第二级第一项</a>
</li>
</ul>
</li>
<li class="the-item">
<a href="javascript:;" class="title">第一级第二项</a>
</li>
<li class="the-item">
<a href="javascript:;" class="title">第一级第三项</a>
</li>
</ul>
</div>
<!-- IMPORT JS -->
</body>
</html>
<script>
const theObject = (function () {
let zTree = document.querySelector(".container>#zTree");
// console.log(zTree);
zTree.onclick = function (e) {
if (e.target.tagName === "EM") {
// console.log(e.target.classList.contains("open"));
let siblingUl = e.target.nextElementSibling;
// console.log([e.target], siblingUl);
if (e.target.classList.contains("open")) {
e.target.classList.remove("open");
siblingUl.style.display = "none";
// continue
} else {
e.target.classList.add("open");
siblingUl.style.display = "block";
}
}
};
const getData = function getData() {
const thePromise = new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open("GET", "./data.json", true);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
let data = JSON.parse(xhr.response);
// console.log(data);
resolve(data);
}
};
xhr.send();
});
return thePromise;
};
// getData();
// getData()
// .then((value) => {
// console.log("方法一thePromise.then().catch()", value);
// })
// .catch((err) => {
// console.log(err);
// });
// const render = async function render() {
// try {
// let data = await getData();
// console.log("方法二async-await", data);
// } catch (err) {
// console.log(err, "执行中断");
// }
// };
// render();
const toLiListString = function toLiListString(liDataList) {
let theString = ``;
// console.log(liDataList);
liDataList.forEach((item, index) => {
console.log(item);
let { name, children, open } = item;
theString += `
${name}
${
children?.length
? `
${open ? `open` : ``}">
${open ? `block` : `none`}
">
${toLiListString(children)}
`
: ``
}
`;
});
return theString;
};
const render = async function render() {
let data = await getData();
const htmlString = toLiListString(data);
zTree.innerHTML = htmlString;
};
render();
})();
</script>
npm就是包管理器。
想要使用npm包管理器,就要先安装node.js。
到node.js官网上,下载稳定版。
下载好之后一直点击下一步,最好用默认方式,别乱改路径。
node_modules
文件夹npm init -y//会在当前文件夹中创建package.json这个文件
下载资源包
npm install 资源包名称 --save//完全
// npm install(简写:i) XXX (--save省略)
// npm install XXX --save(简写:-S)
npm i XXX
npm i XXX -S
下载资料包
npm install(简写:i) XXX --save-dev(简写:-D)
npm i XXX -D
删除资料包 npm uninstall(简写:uni) XXX
资料包的网站:https://www.npmjs.com/(国外网站),只要这个网站上含有的资料包都可以下载
安装指定版本
npm i [email protected](版本号)
查看版本号
npm view XXX versions
alpha 内测版{不稳定,有BUG}
beta 公测版
rc 最终测试版「和正式版差不多了」
stable 正式稳定版(不写)
最后一个稳定版
npm i XXX@latest
最后一个即将发布版本(最后一个测试内测版本)
npm i XXX@next
全局安装(前面的路径随意) :安装到你的电脑的某个位置(电脑规定的文件夹)
电脑上的任何文件都可以用
只能安装1个版本
本地安装(前面的路径自己规定的文件夹) :直接安装到自己规定文件夹
只能在当前文件夹里使用
可以安装多个版本(多个文件夹 1文件夹–版本1 2文件夹–版本2)
全局安装(前面的路径随意)
npm i xxx --global(简写: -g)
苹果电脑全局安装要加***** sudo
sudo npm i xxx -g 还有可能输入 密码
查看全局安装目录
npm root -g
删除全局安装
npm uni xxx --g
git 下载的资料文件家中都不会含有 node_modules,又需要node_modules
*****跑环境:(依据 package.json)
npm i (开发环境和生产环境都跑下来)
npm i --production(只跑生产环境(dependencies))
1.下载加速(去国内站点下载)淘宝镜像
1.1使用淘宝镜像(下载cnpm)
npm install -g cnpm --registry=https://registry.npm.taobao.org
1.2使用cnpm(有可能有点小问题 丢包)
之后使用 cnpm 来代替 npm,----》cnpm和npm可以共存
2.下载加速(去国内站点下载)yarn*****
2.1 下载yarn npm i yarn -g
2.2 yarn init -y
2.3 yarn add XXX
yarn add xxx --dev 安装开发依赖
2.4 yarn remove XXX
yarn add/remove xxx/xxx@xxx/xxx@latest…
2.5跑环境
yarn install
yarn install --production
2.6全局安装
yarn global add xxx 很少用
还用yarn 要保证有 yarn.lock----》yarn install
清屏:cls 苹果(clear)
ctrl+c(多次) —>y 中断命令