1,async异步函数、awite同步语法
async函数和awite 一般结合使用,实现以同步语法,获得异步promise结果,它是对promise用法升级优化
1.1 async异步函数的特点:
async异步函数解决多异步任务并发执行问题的优化
async函数的返回值总是一个promise对象,有以下三种情况:
- 如果没有写返回值,则得到一个空的promise对象,resolve数据是undefined
- 如果返回值是数据,则得到一个非空的promise对象,resolve数据是返回的数据
- 如果返回值是自定义的promise对象,则直接得到这个对象
async function add1(a, b) {
return a + b;
}
console.log(2, add1(2, 3));//2 promise{5}
add1(2, 3).then(res => { console.log(res); });//5
async function add2(a, b) {
return new Promise(function(resolve) {
resolve("abc")
})
}
add2(2, 3).then(res => { console.log(res); });//abc
1.2 awite同步语法,获取promise对象异步结果
awite放在一个promise对象前,会等待promise异步结果,然后返回值的形式拿到异步结果,使异步结果更简单方便的获取,避免了回调的嵌套结构,省略了then函数调用
var p = new Promise(function(resolve) {
setTimeout(() => {
resolve("成功")
}, 100);
});
// 正常情况下,一般在promise对象的then方法的回调中拿到结果
p.then(function(res) { console.log(4, res); });
var res = await p;
1.2.1 awite可以使用同步返回值的形式拿到异步promise的结果的原因
awite通过阻塞进程,使同步代码暂停执行,等promise异步任务得到结果后,继续执行同步指令,所以awite仅允许在异步函数中使用,它指挥阻塞异步函数中的同步代码,不会阻塞整个进程
console.log(0);
async function fun() {
console.log(1);
var data = await p
console.log(2);
console.log(3, data);
}
fun()
console.log(4);//0 1 4 2 3成功
打印的顺序应该是:0 ,1,4,2,3,在函数fun中同步代码按顺序执行,所以先执行打印1,然后执行awite,awite使同步代码暂停执行,等promise异步任务得到结果后,继续执行同步指令,所以要等待promise异步任务得到结果后才能让函数中的同步代码继续执行,所以先执行4,等到结束后再继续执行awite下边的同步代码。
1.3 异步函数用法举例
var p1 = new Promise(function(resolve) {
fs.readFile("./data/a.txt", function(err, data) {
resolve(data)
})
})
var p2 = new Promise(function(resolve) {
fs.readFile("./data/b.txt", function(err, data) {
resolve(data)
})
})
var p3 = new Promise(function(resolve) {
fs.readFile("./data/c.txt", function(err, data) {
resolve(data)
})
})
var p4 = new Promise(function(resolve) {
fs.readFile("./data/d.txt", function(err, data) {
resolve(data)
})
});
// 多异步任务并发执行方案一:promise合并
// var allP = Promise.all([p1, p2, p3, p4])
// allP.then(function(res) {
// console.log(res.join(""));
// })
// 多异步任务并发执行方案二:异步函数
async function getData() {
var data1 = await p1;
var data2 = await p2;
var data3 = await p3;
var data4 = await p4;
console.log(data1 + data2 + data3 + data4);
}
getData();
// 多异步任务并发执行方案三:异步函数
async function getData() {
var data1 = await p1;
var data2 = await p2;
var data3 = await p3;
var data4 = await p4;
return data1 + data2 + data3 + data4
}
getData().then(function(res) {
console.log(res);
});
2,ES6模块化
最新版的node支持最新版ESMScript几乎所有特性,但有一个特性却一直到现在都还没有支持,那就是从ES2015开始定义的模块化机制,但可以使用babel插件使node支持ES6模块化
2.1 ES6模块化全部导入和导出
ES6模块化使用export default{}全部导出,使用import from 全部导入
var count = 100;
var zhangsan = { name: "张三" }
function add(a, b) {
console.log(a + b);
}
// ES6模块化导出 全部导出
export default { count, zhangsan, add }
// 使用ES6模块化语法导入,全部导入
import myModule2 from "./myModule";
console.log(myModule2);//{ count: 100, zhangsan: { name: '张三' }, add: [Function: add] }
2.2 ES6模块化按需导入和导出
ES6模块化使用export {}按需导出,使用import {} from 按需导入
// ES6模块化导出 按需导出
export { count, zhangsan, add }
// 使用ES6模块化语法导入 按需导入
import { count } from "./myModule";
console.log(count);
总结:
node模块化和ES6模块化的区别和使用场景:
- node模块化属于后端模块化,写服务器相关代码时使用
- ES6模块属于前端模块化,写前端页面时使用(vue,react中使用)
2.3 node中是使用ES6模块化
2.3.1 命令行执行: npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/node
2.3.2 再执行:npm isntall --save @babel/polyfill
2.3.3 在项目根目录中创建babel.config,js文件,然后加入以下代码:
const presets = [
[
"@babel/env", {
targets:{
edge: "17",
firefox: "60",
chrome: "67",
safari: "11.1"
}
}
]
];
module.exports = {presets};
2.3.4 完成上述步骤,即可在命令行中通过npx babel-node index.js执行index.js文件
index.js文件可以是任意js文件,要保持要执行的js文件路径正确
3,HTML5新增
3.1 语义化标签
html5新增的语义化标签有哪些?
- 页面结构化标签:header,main,nav,footer,aside,section
- 文字表示类标签:strong,del,u等
- 音视频标签:video,audio
3.1.1 使用语义化标签实现的页面结构
<header>
<nav>网页头部导航</nav>
</header>
<main>
<section>搜索模块</section>
<section>常用链接</section>
<section>新闻</section>
<section>推荐</section>
</main>
<aside>
侧边栏
</aside>
<footer>网页尾部</footer>
3.1.2 什么是语义化?语义化的好处是什么?
html语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析;
即使在没有样式CSS情况下也以一种文档格式显示,并且是容易阅读的;
搜索引擎的爬虫也依赖于HTML标记来确定上下文和各个关键字的权重,利于SEO;
使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。
3.2 音视频标签
<video src="./1.mp4" autoplay loop></video>
<main>
<audio src="./时间煮雨.mp3" autoplay controls loop id="myAudio" data-title="时间煮雨"></audio>
<button onclick="change()">切歌</button>
<button onclick="voice()">静音/解除</button>
<button onclick="play()">暂停/播放</button>
</main>
<script>
var audio = document.getElementById("myAudio")
function change(){
console.log(audio.src, audio.dataset.title)
audio.load() //重置音频
if(audio.dataset.title == "时间煮雨"){
audio.src = "./雨的印记.mp3"
audio.dataset.title = "雨的印记"
}else{
audio.src = "./时间煮雨.mp3"
audio.dataset.title = "时间煮雨"
}
audio.play()
}
function voice(){
console.log(audio.volume) // [0,1]
if(audio.volume == 0){
audio.volume = 1
}else{
audio.volume = 0
}
}
function play(){
// 播放状态,
console.log(audio.paused)
if(audio.paused){
audio.play()
}else{
audio.pause()
}
}
</script>
- autoplay 自动播放,controls 音视频组件显示
3.3 背景渐变
背景渐变设置的是背景图,不是背景色
- linear-gradient:线性渐变
- radial-gradient:径向渐变
- 渐变叠加:要求上层的颜色有透明才能看到下层颜色
<style>
div{
width: 300px;
height: 300px;
border: 1px solid;
background-color: aqua;
/* 背景渐变设置的是背景图,不是背景色 */
/* linear-gradient 线性渐变 */
background-image: linear-gradient(red, yellow, blue);
/* radial-gradient 径向渐变 */
background-image: radial-gradient(red, yellow, blue);
/* 渐变叠加 要求上层的颜色有透明才能看到下层颜色*/
background-image: linear-gradient(blue, transparent, blue), radial-gradient(black, yellow, blue);
}
</style>
<body>
<div></div>
</body>
3.4 css滤镜
滤镜效果:
- grayscale:灰度
- sepia:褐色
- saturate:饱和度
- hue-rotate:色相旋转
- invert:反色
- opacity:透明度
- brightness:亮度
- contrast:对比度
- blur:模糊
<style>
img:nth-child(2){
/* 灰度滤镜: 范围[0,1] 默认0 1表示黑白*/
filter: grayscale(1);
}
img:nth-child(3){
/* 褐色滤镜: 范围[0,1] 默认0 1表示褐色*/
filter: sepia(1)
}
img:nth-child(4){
/* 饱和度滤镜: 范围[0, ∞] 默认1 0表示黑白*/
filter: saturate(2)
}
img:nth-child(5){
/* 色相滤镜: 范围 [0deg, 360deg] 默认0deg */
filter: hue-rotate(180deg);
}
img:nth-child(6){
/* 反色滤镜: 范围 [0,1] 默认0 */
filter: invert(1);
}
img:nth-child(7){
/* 透明滤镜: 范围 [0,1] 默认1 */
filter: opacity(0.5)
/* opacity: 0.5; */
}
img:nth-child(8){
/* 亮度滤镜: 范围[0, ∞] 默认1 0表示纯黑*/
filter: brightness(1.3);
}
img:nth-child(9){
/* 对比度滤镜: 范围[0, ∞] 默认1 0表示纯灰*/
filter: contrast(1.5);
}
img:nth-child(10){
/* 模糊滤镜: 范围 [0px, ∞px] 默认0px 越长越模糊*/
filter: blur(5px);
}
img:nth-child(11){
margin: 50px; width: 300px;
/* 阴影滤镜: 向右偏移量 向下偏移量 阴影扩散距离 颜色 */
filter: drop-shadow(10px 10px 10px red);
}
img:nth-child(12){
margin: 50px; width: 300px;
/* 盒子阴影 */
box-shadow: 10px 10px 30px red;
}
body{
font-size: 40px;
text-shadow: 20px 20px 5px blue;
}
/* 区别:
滤镜阴影设置的是图片轮廓, 适用于png图片标签
文字阴影设置的是文字轮廓, 只用于文字
盒子阴影设置的是标签盒子, 所有标签都能用*/
</style>
<body>
<img src="item932.jpg" alt="">
<img src="item932.jpg" alt="">
<img src="item932.jpg" alt="">
<img src="item932.jpg" alt="">
<img src="item932.jpg" alt="">
<img src="item932.jpg" alt="">
<img src="item932.jpg" alt="">
<img src="item932.jpg" alt="">
<img src="item932.jpg" alt="">
<img src="item932.jpg" alt="">
<img src="fengche.png" alt="">
<img src="fengche.png" alt="">
<h1>窗前明月光,地上鞋两双</h1>
</body>