ES6基础内容
ES 全称 EcmaScript ,是脚本语言的规范,而平时经常编写的 JavaScript 是 EcmaScript 的一种实现,所以 ES 新特性其实指的就是 JavaScript 的新特性。
一、 let变量声明和声明特性
1.1 变量声明
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let a;
let b,c,d;
let e=521;
let f=100,g='iloveyou',h=[];
</script>
</body>
</html>
1.2 声明特性
1.2.1 变量不能重复声明
当用let声明两个变量名一样时,会报错。
1.2.2 块级作用域
es5作用域分为:
- 全局
- 函数
- eval
es6引入新的作用域:块级作用域
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
{
let name='小羊苏西';
}
console.log(name);
</script>
</body>
</html>
在块之外读取不到该变量,如下:
将let改为var后,可读取到变量:
主要用于:if else for while 后的{}中。
1.2.3 不存在变量提升
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
console.log(age);
var age=18;
console.log(addr);
let addr='山东省'
</script>
</body>
</html>
var 声明的变量存在变量提升,可在声明变量之前使用该变量而不会报错,而
let 声明的变量不存在变量提升,在声明变量之前使用该变量会报错。
var 声明的变量相当于在一开始就声明了该变量,只是没有赋值,故输出undefined。
1.2.4 不影响作用域链
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
{
let phone=12345;
function fun(){
console.log(phone);
}
fun();
}
</script>
</body>
</html>
在块级作用域中,可正常按照作用域来执行。
1.3 案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h3>点击切换颜色</h3>
<div class="box">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<script>
//获取div元素
let items=document.getElementsByClassName('item');
//遍历并绑定事件
for(var i=0;i<items.length;i++){
items[i].onclick = function(){
//修改当前元素的背景颜色
items[i].style.background='pink';
}
}
</script>
<style>
.box{
width: 350px;
display: flex;
justify-self: start;
}
.item{
width: 100px;
height: 70px;
margin-left: 5px;
border: 1px solid blue;
}
</style>
</body>
</html>
当使用 var 来定义 i 时,当执行点击函数内部的 items[i] 时,会向外读取 i 的值,而读取到的 i 为3,会报错,可使用 this.style.background='pink' 来实现该效果。
改为 let 来声明,由于具有块级作用域,读取到的 i 可为 0,1,2,不会报错。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h3>点击切换颜色</h3>
<div class="box">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
<script>
//获取div元素
let items=document.getElementsByClassName('item');
//遍历并绑定事件
for(let i=0;i<items.length;i++){
items[i].onclick = function(){
//修改当前元素的背景颜色
items[i].style.background='pink';
}
}
</script>
<style>
.box{
width: 350px;
display: flex;
justify-self: start;
}
.item{
width: 100px;
height: 70px;
margin-left: 5px;
border: 1px solid blue;
}
</style>
</body>
</html>
效果图如下:
二、const声明常量和特点
2.1 声明格式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const NAME='小羊苏西';
</script>
</body>
</html>
2.2 特点
-
一定要赋初始值;
-
一般常量使用大写;
-
常量的值不能修改;
-
块级作用域;
-
对于数组和对象的元素修改,不算对常量的修改,不会报错。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const NAME=['张三','李四'];
NAME.push('赵五');
</script>
</body>
</html>
对数组和对象的元素修改,并不影响常量指向的地址,不会报错。
三、变量的解构赋值
ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值。
3.1 数组的解构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const TF=['王俊凯','王源','易烊千玺'];
let [no1,no2,no3]=TF;
console.log(no1);
console.log(no2);
console.log(no3);
</script>
</body>
</html>
3.2 对象的解构
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const WJK={
name:'王俊凯',
age:25,
talent:function(){
console.log('擅长唱歌跳舞');
}
}
let {name,age,talent}=WJK;
console.log(name);
console.log(age);
talent();
</script>
</body>
</html>
四、模板字符串
es5声明字符串方式:' '," ";
es6新增:` `
4.1 声明格式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let str=`我是一个字符串`;
console.log(str,typeof(str));
</script>
</body>
</html>
4.2 特点
4.2.1 内容中可以直接出现换行符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let str=`<ul>
<li>王俊凯</li>
<li>王源</li>
<li>易烊千玺</li>
</ul>`;
</script>
</body>
</html>
` `使用换行符时并不会出现错误
' '和" "会报错。
4.2.2 字符拼接
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let name='王俊凯';
let res=`${name}擅长唱歌跳舞`;
console.log(res);
</script>
</body>
</html>
五、对象简化写法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let name=`小田`;
let change=function(){
console.log('我们可以改变');
}
const res={
//name:name
name,
//change:change
change,
// fun:function(){
// console.log("我们在学校");
// }
fun(){
console.log("我们在学校");
}
}
console.log(res);
</script>
</body>
</html>
六、箭头函数
6.1 声明格式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let fun=(a,b)=>{
return a+b;
}
let res=fun(1,2);
console.log(res);
</script>
</body>
</html>
6.2 特点
6.2.1 this是静态的
始终指向函数声明时所在作用域下的this值
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function getName(){
console.log(this.name);
}
let getName1=()=>{
console.log(this.name);
}
//设置 window 对象的 name 属性
window.name='小田';
const temp={
name:'xiaotian'
}
//直接调用
getName();
getName1();
console.log("————————")
//call方法调用
getName.call(temp);
getName1.call(temp);
</script>
</body>
</html>
call方法可以改变函数内部this值
6.2.2 不能作为构造实例化对象
6.2.3 不能使用 arguments 变量
6.2.4 箭头函数简写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//省略小括号,当形参有且只有一个的时候
let add= n =>{
return n+n;
}
console.log(add(9));
//省略花括号,当代码体只有一条语句的时候,此时return必须省略
//语句执行结果就是函数返回值
let pow=(n)=>n*n;
console.log(pow(9));
</script>
</body>
</html>
七、函数参数默认值
ES6允许给参数参数赋值初始值
7.1 形参初始值
具有默认的参数,一般位置要靠后
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function add(a,b,c){
return a+b+c;
}
let res=add(1,2,3);
console.log(res);
//当c没有传值时,为undefined,相加为NaN
let res1=add(1,2);
console.log(res1);
function add1(a,b,c=10){
return a+b+c;
}
//当c有传值时,用所传的值覆盖初始值
let res2=add1(1,2,3);
console.log(res2);
//当c没有传值时,用初始值
let res3=add1(1,2);
console.log(res3);
</script>
</body>
</html>
7.2 与解构赋值结合
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function connect({host="127.0.0.1",username,password,port}){
console.log(host);
console.log(username);
console.log(password);
console.log(port);
}
connect({
host:'localhost',
username:'root',
password:'root',
port:3306
})
//无host值,使用默认值·
connect({
username:'tian',
password:123456,
port:8080
})
</script>
</body>
</html>
八、rest参数
ES5获取实参方式:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function data(){
console.log(arguments);
}
data('王俊凯','王源','易烊千玺');
</script>
</body>
</html>
ES6引入 rest 参数,用于获取参数的实参,来替代 arguments。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function data(...args){
console.log(args);
}
data('王俊凯','王源','易烊千玺');
//rest参数必须要放到参数最后
function fn(a,b,...args){
console.log(a);
console.log(b);
console.log(args);
}
fn(1,2,3,4,5,6);
</script>
</body>
</html>
arguments 获取的是对象,而 rest 参数类型获取的是数组形式。
九、扩展运算符
... 扩展运算符能将数组转换成逗号分隔的参数序列
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const tfboys=['王俊凯','王源','易烊千玺'];
// =>'王俊凯','王源','易烊千玺'
function fn(){
console.log(arguments);
}
fn(tfboys);
console.log('----------')
fn(...tfboys);
// => fn('王俊凯','王源','易烊千玺')
</script>
</body>
</html>
9.1 应用
9.1.1 数组的合并
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const heze=['曹县','定陶'];
const taian=['岱岳区','泰山区'];
const shandong=heze.concat(taian);
console.log(shandong);
const shandong1=[...heze,...taian];
console.log(shandong1);
</script>
</body>
</html>
9.1.2 数组的克隆
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const arr=['a','b','c'];
const arr1=[...arr];
console.log(arr1);
</script>
</body>
</html>
9.1.3 伪数组转换成真正数组
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div></div>
<div></div>
<div></div>
<script>
const divs=document.querySelectorAll('div');
const divArr=[...divs];
console.log(divs);
console.log(divArr);
</script>
</body>
</html>
十、Symbol
ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol 特点
- Symbol 的值是唯一的,用来解决命名冲突的问题
- Symbol值不能与其他数据进行运算
- Symbol定义的对象属性不能使用 for..in 循环遍历,但是可以使用Reflect.ownKeys 来获取对象的所有键名
JS七种数据类型:
undefined
string 、symbol
object
null 、number·
boolean
10.1 symbol创建
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let s=Symbol();
console.log(s,typeof s);
//tian相当于一个名称或注释,描述字符串
let s1=Symbol('tian');
let s2=Symbol('tian');
console.log(s1===s2);
let s3=Symbol.for('tian');
let s4=Symbol.for('tian');
console.log(s3===s4);
//不能与其他数据进行运算
let res=s+100;
let res1=s>100;
let res2=s+s;
</script>
</body>
</html>
10.2 symbol使用
给对象添加属性和方法,表示独一无二的
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
let game={
name:'王者荣耀',
up:'我上升到王者了',
down:'我下降到砖石了',
};
//当想向game对象添加方法 up down
// game.up=function(){},当game对象内部未知,使用可能有冲突
let methods={
up:Symbol(),
down:Symbol()
};
game[methods.up]=function(){
console.log("我上星了");
}
game[methods.down]=function(){
console.log("我掉星了");
}
console.log(game);
let youxi={
name:'狼人杀',
[Symbol('say')]:function(){
console.log("我可以发言");
},
[Symbol('zibao')]:function(){
console.log("我要自爆");
}
};
console.log(youxi);
</script>
</body>
</html>
10.3 symbol内置属性
Symbol.hasInstance | 当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法 |
Symbol.isConcatSpreadable | 对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于 Array:prototype.concat()时,是否可以展开。 |
Symbol.unscopables | 该对象指定了使用 with 关键字时,哪些属性会被 with环境排除。 |
Symbol.match | 当执行 str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值。 |
Symbol.replace | 当该对象被 str.replace(myObject)方法调用时,会返回该方法的返回值。 |
Symbol.search | 当该对象被 str. search(myObject)方法调用时,会返回该方法的返回值。 |
Symbol.split | 当该对象被 str. split (myObject)方法调用时,会返回该方法的返回值。 |
Symbol.iterator | 对象进行 for..of循环时,会调用Symbol.iterator 方法,返回该对象的默认遍历器。 |
Symbol.toPrimitive | 该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。 |
Symbol. toStringTag | 在该对象上面调用 toString 方法时,返回该方法的返回值。 |
Symbol.species | 创建衍生对象时,会使用该属性。 |
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
class Person{
static [Symbol.hasInstance](param){
console.log(param);
console.log(1111111);
}
}
let o={};
console.log(o instanceof Person);
console.log('------------');
const arr=[1,2,3];
const arr1=[4,5,6];
console.log(arr.concat(arr1));
arr1[Symbol.isConcatSpreadable]=false;
console.log(arr.concat(arr1));
</script>
</body>
</html>
十一、迭代器
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作。
ES6 创造了一种新的遍历命令 for..of 循环,lterator 接口主要供 for..of 消费
原生具备iterator 接口的数据(可用for of遍历):
Array、Arguments、Set、Map、String、TypedArray、NodeList
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const tfboys=['王俊凯','王源','易烊千玺'];
//for...of 中表 键值
for(let v of tfboys){
console.log(v);
}
//for...in 中表 下标
for(let v in tfboys){
console.log(v);
}
</script>
</body>
</html>
工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的next 方法,指针自动指向数据结构的第一个成员
- 接下来不断调用 next 方法,指针一直往后移动,直到向最后一个成员
- 每调用 next方法返回一个包含 value 和 done 属性的对象
需要自定义遍历数据的时候,要想到迭代器。
11.1 自定义遍历数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const clazz={
name:'1班',
stus:[
'张三',
'李四',
'王五'
],
[Symbol.iterator](){
//索引变量
let index=0;
let _this=this;
return{
next:function(){
if(index<_this.stus.length){
const res={
value:_this.stus[index],
done:false
};
//下标自增
index++;
//返回结果
return res;
}else{
return {value:undefined,done:true};
}
}
};
}
}
for(let v of clazz){
console.log(v);
}
</script>
</body>
</html>
十二、生成器
生成器函数其实是一种特殊的函数,用于异步编程
12.1 声明与调用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//声明
function * gen(){
console.log("hello tian")
}
//调用
let iterator=gen();
iterator.next();
</script>
</body>
</html>
生成器函数可用 yield 函数代码的分隔符
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function * gen(){
console.log(111);
yield '一只没有耳朵';
console.log(222);
yield '一只没有尾巴';
console.log(333);
yield '真奇怪';
console.log(444);
}
function * gen1(){
yield '一只没有耳朵';
yield '一只没有尾巴';
yield '真奇怪';
}
//调用
let iterator=gen();
//只输出每个模块中的输出内容
iterator.next();
iterator.next();
iterator.next();
iterator.next();
console.log("---------------");
let iterator1=gen1();
//会输出返回的value值
console.log(iterator1.next());
console.log(iterator1.next());
console.log(iterator1.next());
console.log(iterator1.next());
console.log("---------------");
for(let v of gen1()){
console.log(v);
}
</script>
</body>
</html>
12.2 参数传递
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function * gen(arg){
console.log(arg);
let one=yield 111;
console.log(one);
let two=yield 222;
console.log(two);
let three=yield 333;
console.log(three);
}
//arg接受AAA
let iterator=gen('AAA');
//输出第一模块间语句,并且输出第一条yield
console.log(iterator.next());
//next方法可以传入实参,作为上一条yield语句的返回值
console.log(iterator.next('BBB'));
console.log(iterator.next('CCC'));
console.log(iterator.next('DDD'));
</script>
</body>
</html>
12.3 案例
1s后控制台输出111,2s后输出222,3s后输出333。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//回调地狱,此方法不建议
setTimeout(()=>{
console.log(111);
setTimeout(()=>{
console.log(222);
setTimeout(()=>{
console.log(333);
},3000)
},2000)
},1000)
function one(){
setTimeout(()=>{
console.log(111);
iterator.next();
},1000)
}
function two(){
setTimeout(()=>{
console.log(222);
iterator.next();
},2000)
}
function three(){
setTimeout(()=>{
console.log(333);
iterator.next();
},3000)
}
function * gen(){
yield one();
yield two();
yield three();
}
let iterator=gen();
iterator.next();
</script>
</body>
</html>
模拟获取 用户数据 订单数据 商品数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
function getUsers(){
setTimeout(()=>{
let data='用户数据';
iterator.next(data);
},1000);
}
function getOders(){
setTimeout(()=>{
let data='订单数据';
iterator.next(data);
},1000);
}
function getGoods(){
setTimeout(()=>{
let data='商品数据';
iterator.next(data);
},1000);
}
function * gen(){
let users=yield getUsers();
console.log(users);
let oders=yield getOders();
console.log(oders);
let goods=yield getGoods();
console.log(goods);
}
let iterator=gen();
iterator.next();
</script>
</body>
</html>
十三、Promise
13.1 基本使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//实例化Promise对象,参数为函数,函数的参数resolve表示成功,reject表示失败
const p=new Promise(function(resolve,reject){
setTimeout(function(){
let data='用户数据';
resolve(data);
},1000);
})
//参数为两个函数,第一个函数对应resolve成功执行,第二个函数对应reject失败执行
p.then(function(value){
console.log(value);
},function(reason){
console.error(reason);
})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
//实例化Promise对象,参数为函数,函数的参数resolve表示成功,reject表示失败
const p=new Promise(function(resolve,reject){
setTimeout(function(){
let err='数据读取失败';
reject(err);
},1000);
})
//参数为两个函数,第一个函数对应resolve成功执行,第二个函数对应reject失败执行
p.then(function(value){
console.log(value);
},function(reason){
console.error(reason);
})
</script>
</body>
</html>
调用 resolve 后,p 的状态变为成功,并调用 p.then() 参数中第一个函数;
调用 reject 后,p 的状态变为失败, 并调用 p.then() 参数中第二个函数。
13.2 读取文件
const fs=require('fs');
const { resourceLimits } = require('worker_threads');
//1.调用方法读取文件
fs.readFile('./静夜思.md',(err,data)=>{
//如果失败,则抛出异常
if(err) throw err;
//如果成功,则输出内容
console.log(data.toString());
});
//2.使用Promise封装
const p=new Promise(function(resolve,reject){
fs.readFile("./静夜思.md",(err,data)=>{
if(err) reject(err);
resolve(data);
});
});
p.then(function(value){
console.log(value.toString());
},function(reason){
console.log("读取失败!!");
})
13.3 封装AJAX请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const p=new Promise((reslove,reject)=>{
//1.创建对象
const xhr=new XMLHttpRequest();
//2.初始化
xhr.open("GET","https://api.apiopen.top/getJoke");
//3.发送
xhr.send();
//4.绑定事件,处理响应结果
xhr.onreadystatechange=function(){
if(xhr.readyState===4){
if(xhr.status>=200 && xhr.status<300){
//表示成功
reslove(xhr.response);
}else{
//如果失败
reject(xhr.status);
}
}
}
});
//指定回调
p.then(function(value){
console.log(value);
},function(reason){
console.error(reason);
})
</script>
</body>
</html>
13.4 then方法
调用 then 方法, then 方法的返回结果是 Promise 对象,对象状态由回调函数的执行结果决定。
如果回调函数中返回的结果是 非Promise 类型的属性,状态为已完成,返回值为对象的成功的值;
是 Promise 对象,状态为已完成,返回值为 调用 resolve 或 reject 传的值;
抛出异常,状态为失败,返回值为 抛出的异常值;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const p=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("用户数据");
},1000)
});
//返回结果为非promise对象,不写return默认为undefined
const res=p.then(value=>{
console.log(value);
return 123;
},reason=>{
console.warn(reason);
})
console.log(res);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const p=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("用户数据");
},1000)
});
//返回结果为非promise对象,不写return默认为undefined
const res=p.then(value=>{
console.log(value);
return new Promise((resolve,reject)=>{
resolve("ok");
})
},reason=>{
console.warn(reason);
})
console.log(res);
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const p=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("用户数据");
},1000)
});
//返回结果为非promise对象,不写return默认为undefined
const res=p.then(value=>{
console.log(value);
throw "出错啦!!!";
},reason=>{
console.warn(reason);
})
console.log(res);
</script>
</body>
</html>
可进行链式调用!!!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
const p=new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("用户数据");
},1000)
});
p.then(value=>{
},reason=>{
}).then(value=>{
},reason=>{
});
</script>
</body>
</html>