参考笔记:ES6开发必备基本用法_牛肉粉面的博客-CSDN博客
参考倔金:ES6常用API详讲 - 掘金
相关手写代码:
<!--
* @Author: kjpkjp 9361167+kjpkjp@user.noreply.gitee.com
* @Date: 2022-09-09 20:36:34
* @LastEditors: kjpkjp 9361167+kjpkjp@user.noreply.gitee.com
* @LastEditTime: 2022-09-12 21:12:09
* @FilePath: \adminc:\Users\asus\Desktop\train.html
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="http://libs.baidu.com/jquery/2.1.4/jquery.min.js"></script>
<title>Document</title>
</head>
<body>
<script>
let add = function (a, b) {
return a + b;
}
let add1 = (var1, var2) => (var1 + var2)
console.log(add(5, 6))
console.log(add(5, 6))
let getObj = id => {
return {
id: id,
name: 'heihei'
}
}
let getObj1 = id => ({
id: id,
name: 'heihei'
})
console.log(getObj(1))
//8.扩展对象的功能
//8.1方法简写 原来是 let set =function(){} 现在 set(){}
console.log('8.扩展对象的功能');
let cart = {
wheel: 4,
set(newVal) {
if (newVal < this.wheel) {
throw new Error('轮子太少')
}
this.wheel = newVal
},
get() { //取值器
return this.wheel
}
}
console.log(cart.get())
cart.set(6)
//8.2对象的追加属性【属性名】
const obj = {};
obj.isshow = true;
const name = 'aaaa';
obj[name + 'bbbb'] = 123468;
console.log(obj);
//8.3对象的方法 Object.is() ===
// 对象的方法:
// is() 和 ===
// 比较两个值是否严格相等
console.log(NaN === NaN); // false ,===有缺陷
// console.log(Obejct.is(NaN, NaN)); // true
//8.4 对象的合并
// assign()
//Object.assign(target,obj1,obj2,...) 返回合并之后的新对象
// 对象的合并
/* let newObj = Object.assign({}, { a: 1 }, { b: 2 });
console.log(newObj); // {a: 1, b: 2}
*/
//9 Symbol 独一无二的数据
let sy1 = Symbol('hello');
let sy2 = Symbol('hello');
console.log(sy1 == sy2, 'sy1==sy2');
console.log(sy1 === sy2);
// 10 map和set集合
//集合中唯一,无重复的值
let set = new Set()
console.log(set);
//10.1 添加元素 add()
set.add(2);
set.add('4');
set.add('4'); // 这个4会被忽略,因为集合表示无重回复值的有序列表
console.log(set); // set(2) {2, "4"}
//10.2 也可以添加数组
set.add([1, 2, 3]);
//10.3 删除元素 delete()
set.delete(2);
console.log(set);
//10.4校验某个值是否在 set 中 has()
console.log(set.has('4')); // 返回 true
//10.5 访问集合的长度
console.log(set.size);
//10.6 set 转换成 数组
let set2 = new Set([1, 2, 3, 4]);
// 使用扩展运算符来转换
let arr = [...set2];
console.log(arr);
//10.7
let set4 = new WeakSet(), obj5 = {}; //一行写两个定义
console.log(set4);
set4.add(obj5)
obj5 = null;
console.log(set4)
//10.8 map键值对
let map = new Map()
map.set(['a', [1, 2, 3]], 'hello');
console.log(map);
let m = new Map([
['a', 1],
['b', 2]
])
console.log(m);
//11 数组
let list = 'helloww'
//利用扩展运算符,转换为真正的数组
console.log([...list]);
//11.1 copyWithin()
// 表示将从 3 号位直到数组结束的成员(8,9,10),替换到从 0 号位开始的位置,结果覆盖了原来的 1, 2, 3。
console.log([1, 2, 3, 8, 9, 10].copyWithin(0, 3)); // [8, 9, 10, 8, 9, 10];
console.log([1, 2, 3, 8, 9, 10].copyWithin(-2, 3)); // [8, 9, 10, 8, 9, 10];
//12.遍历器 values(),keys(),entries()
for (let index of ['a', 'b', 'c'].values()) {
console.log(index)
}
//14迭代器 iterator 迭代器是一个接口,能快捷的访问数据,
//*通过items[Symbol.iterator]()是个函数,用来创建迭代器
//迭代器是用于遍历数据结构的指针
const items = ['one', 'two', 'three']
console.log(items);
const iterat = items[Symbol.iterator]()
console.log(iterat.next());
//每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,
//就是返回一个包含value和done两个属性的对象。其中,value属性是当前成员的值,
//done属性是一个布尔值,表示遍历是否结束。
//15生成器 主要解决异步操作
//使用场景:为不具备interator接口的对象提供便利操纵
//一是,function关键字与函数名之间有一个星号 * ;二是,函数体内部使用yield表达式 表达式
function* func() {
console.log('star');
yield '暂停一下';
console.log('第二下star');
yield '暂停结束'
}
//返回一个遍历器对象
let o = func()
console.log(o, '15生成器');
console.log(o.next());
console.log(o.next());
//总结:generator函数是分段执行的,yield语句是暂停执行,而next()是恢复执行
//15.2生成器
// 生成器函数:function关键字与函数名之间有一个星号 * ;函数体内部使用yield表达式
function* add3() {
console.log('start');
// 这里的 x 不是 yield '2' 的返回值,它是下一个 next()调用恢复执行时传入的参数值
let x = yield '2'; // yield 暂停执行标志
console.log('one:' + x);
let y = yield '3'; // yield 暂停执行标志
console.log('two:' + y);
return x + y;
}
// 返回一个遍历器对象
let fn = add3()
// next() 恢复执行标志
console.log(fn.next()); // start {value: '2', done: false}
// 当 next() 传入参数时,该参数就会被当作上一个 ***(上一个 上一个)yield 表达式的返回值 ,即 x = 20, y = 30
console.log(fn.next(20)); // one:20 {value: '3', done: false}
console.log(fn.next(30)); // two:30 {value: '50', done: true}
//15.3 生成器的应用
const obj3 = {
name: 'xxiao',
age: 15
}
console.log(obj3, '查看有没有symbol.iteration接口'); //没有这个迭代器接口啊
//15.4 Generator 生成器函数举例
function* objectEntries(obj4) {
// 获取对象的所有 key 保存到数组 [name, age]
const propKeys = Object.keys(obj4);
for (const propkey of propKeys) {
yield [propkey, obj4[propkey]] //propkey中保存着obj4的键:name和age;obj[propkey]为相对应的值
}
}
const obj4 = {
name: '牛肉粉',
age: 18
}
// 把 Generator 生成器函数 赋值 给对象的Symbol.iterator属性, 为该对象加上遍历器接口
obj4[Symbol.iterator] = objectEntries; //添加遍历接口
console.log(obj4);
//for --of 用来遍历生成器
// objectEntries(obj4) 等价于 obj4[Symbol.iterator](obj4)
for (let [key, value] of objectEntries(obj4)) {
console.log(`${key}:${value}`);
}
//16 生成器的应用
$.ajax({
url: 'https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976',
method: 'get',
success(res) {
console.log(res);
}
})
//16.1 利用生成器将同步请求变为异步请求
function* main() { //生成器定义函数
let res = yield request('http://d1.weather.com.cn/dingzhi/101230201.html?_=" + DateTime.Now.GetDateTimeToLongTimeStamp()')
console.log(res);
//执行后续请求一系列操作
}
let ite = main(); //定义生成器指代名称
ite.next();
function request(url) { //定义request方法
$.ajax({
url,
method: 'get',
success(res) {
ite.next(res); //c此操作将成功回调返回的结果赋值给main中的res
}
})
}
//17 promise 的基本使用
//先定义个promise对像
let pro = new Promise(function (resolved, rejected) {
//执行异步操作
let res = {
code: 200,
data: {
name: 'xxiao'
}
}
//模拟异步行为
setTimeout(() => {
if (res.code === 200) {
resolved(res.data)
}
}, 1000);
})
console.log(pro);
pro.then((succe) => { //then中的回调函数专门接受 resolved返回来的值
console.log(succe);
})
//18 自己封装ajax 自己封装getJson方法
//then里面传了两个回调函数,第一个代表成功之后的回调,第二个代表失败之后的回调,分别代表resolve()和reject()
console.log('18---------------');
const getJson = function (url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = handler;
xhr.resposeType = 'json';
xhr.setRequestHeader('Accept', 'application/json');
xhr.send();
function handler() {
if (this.readyState === 4) {
if (this.status === 200) {
resolve(this.respose);
} else {
reject(new Error(this.statusText))
}
}
}
})
}
getJson('https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976')
.then((data) => {
//then里面传了两个回调函数,第一个代表成功之后的回调,第二个代表失败之后的回调,分别代表resolve()和reject()
console.log(data); //data相当于promise中成功执行之后返回的resolve中的返回值
}, (error) => {
console.log(error);
})
//19 promise 的其他方法 resolve 能将现有的任何对象转换为promise对象
let p = Promise.resolve('成功值')
//等价于let p = new Promise(resolve=>resolve('foo'))
p.then(val => {
console.log(val, '19---------'); //输出成功值 19---------
})
//19.1promise 的all() 方法 一般用于游戏共同资源的请求
let pro1 = new Promise((resolve, reject) => { });
let pro2 = new Promise((resolve, reject) => { });
let pro3 = new Promise((resolve, reject) => { });
let pAll = Promise.all([pro1, pro2, pro3]);
pAll.then(() => {
// 三个都成功 才成功
}).catch(err => {
// 如果一个失败 则失败
})
//19.2小应用 race()的应用 race某个异步请求设置超时时间,并且在超时后执行响应的操作
// 请求图片资源
function requestImg(imgSrc) {
return new Promise((resolve, reject) => {
const img = new Image();
// 加载图片资源
img.onload = function () {
resolve(img);
}
img.src = imgSrc;
});
}
//延时函数,用于给请求计时
function timeout() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('图片请求超时'));
}, 3000);
});
}
// Promise.race()接受一个包含多个promise对象的数组(数组数组),只要有一个完成,就执行success
// 如果3s 之内加载完成就执行 then 方法, 3s 之后还没加载完成就执行 catch 方法
Promise.race([requestImg('https://i2.hdslb.com/bfs/face/59a2cb990fde5e2cd289c3305450664b462da341.jpg@240w_240h_1c_1s.webp'), timeout()]).then((data) => {
console.log(data);
document.body.appendChild(data);
}).catch((err) => {
console.log(err);
});
//20
//20.1 async的应用 使异步操作更加方便
//基本操作 async 她会返回一个promise对像可以调用 太狠 catch
async function funcc() {
let s = await 'hello';
let data = await s.split('');
return data; //这个return 是等待完所有的await之后才执行的
}
//如果 async 函数中有多个 await , 那么 then 函数 会等待所有的 await 指令运行完才去执行
funcc().then(v => { console.log(v, '这是20节的内容async'); }).catch(err => { console.log(err); })
//20.2
async function f2() {
// throw new Error('20出错了');
await Promise.reject('出错了');
await Promise.resolve('hello');
}
f2().then(v => { console.log(v, '这是20节的内容async'); }).catch(err => { console.log(err); })// 返回 出错了
//针对上诉遇到 reject状态,就中断执行的问题,可以通过 try...catch 代码块解决
//20 .3 需求 获取天气 现在 now的数据
/* 获取天气接口 ajax请求*/
const getJson2 = function (url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = handler;
xhr.resposeType = 'json';
xhr.setRequestHeader('Accept', 'application/json');
xhr.send();
function handler() {
if (this.readyState === 4) {
if (this.status === 200) {
resolve(this.respose);
} else {
reject(new Error('获取天气出错'))
}
}
}
})
}
/* 定义 getNowWeather 函数 异步获取 天气请求的返回值*/
async function getNowWeather(url) {
let result = await getJson2(url);
console.log(result, 'result');
let arr = await result.HeWeather6;
return arr[0].now;
}
/* 获取天气调用 */
getNowWeather('https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976').then(now => {
console.log(now, '20.3获取天气');
}).catch(err => {
console.log(err); //这个err返回相当于上面的《=》 reject(new Error('获取天气出错'))
})
//21 类
console.log('21======================');
//21.1 es5 d的构造类 看起来像个函数
function Person(name, age) {
this.name = name;
this.age = age;
}
//构造函数指向原型prototype =====创建原型中的方法
Person.prototype.sayName = function () {
return this.name;
}
let pick = new Person('************************xx小小怪', 18);
console.log(pick);
console.log(pick.sayName());
// 21.2 es6的构造函数
// es6
console.log('es6中的构造函数的写法');
class Kerson {
// 实例化的时候会立即被调用
constructor(name, age) {
this.name = name;
this.age = age;
}
//等同于Person.prototype = function sayName(){}
sayName() {
return this.name;
}
sayAge() {
return this.age;
}
}
// 小技巧:通过 Objec.assign() 方法(详见对象的扩展功能)一次性向类中添加多个方法
/* 给原型上添加方法 用Object.assign()方法
Object.assign(Person.prototype, {
sayName(){
return this.name;
}
sayAge(){
return this.age;
}
})
*/
let p4 = new Kerson('牛肉粉', 18);
console.log(p4);
p4.sayName();
//22继承 建议重听了解 super 和。call(this指向)
class Animal {
// 实例化的时候会立即被调用
constructor(name, age) {
this.name = name;
this.age = age;
}
sayName() {
return this.name;
}
sayAge() {
return this.age;
}
}
//这儿super注意点
class Dog extends Animal {
constructor(name, age, color) {
// 如果 子类 继承了 父类,且 子类 中写了构造器,则 子类 构造器的 super 必须要调用
super(name, age); //会调用父类的构造函数,直接执行zhij 等同于 Animal.call(this,name,age); 继承父类的属性******this指向这儿指向Dog
this.color = color;
}
// 子类自己的方法
sayColor() {
return `${this.name}是${this.age}岁了,它的颜色是${this.color}`;
}
// 重写父类的方法
sayName() {
//***** super 相同于 Animal.prototype
return this.name + super.sayAge + this.color;
}
}
let d1 = new Dog('小黄', 28, 'red');
console.log(d1.sayAge()); // 调用继承父类的方法
console.log(d1.sayColor()); // 调用子类自己的方法
console.log(d1.sayName()); // 调用重写父类的方法
</script>
</body>
</html>
2. let 和 const 的补充
// 例 1
// 底层看到 var ,会自动在前面声明变量,即变量提升,而 let 不会
// 如下代码,会在前面 自动添加 var a; 而不会自动添加 let b;
let a = 10;
var b = 1;
console.log(a) // ReferenceError: a is not defined. 报错
console.log(b) // 1
// 例 2
var a = [];
// 由于变量提升,会在这里自动声明 var = i;
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10 由于变量提升,var i 最后访问到循环十次之后的结果
// let 是一个块作用域,let声明的变量只在它所在的代码块有效。
for (let i = 0; i < 10; i++) {
// ...
}
console.log(i); // ReferenceError: i is not defined
var a = [];
for (let i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 6 因为这儿定义的是let
// 例 3
// var 的重复声明
var c = 1;
var c = 3;
console.log(c); //4
//let 不可以重复声明
let d = 1;
let d = 3;
console.log(d); //报错
// 例 4
//const 声明常量,一旦声明就不能被修改
const max = 30;
max = 40;
console.log(max); //会报错
//修改常量 对象
const person={
name='lisi'
}
person.name='kkk'
4. 函数默认值和剩余参数(补充)
argument就是未知函数有多少参数的时候用 的(函数本身有的属性/方法 )
打印argument(重复3次)
输出:
下图为打印函数中的所有参数(从1开始)
输出:
下图为取出对象中指定的属性的函数pick(): pick中的'title','year'为你要取出的属性名是什么
- 剩余参数
- 由...和一个紧跟着的具名参数组成 : ...keys *****keys可以是任意单词
- ...keys 解决了 arguments 的问题
- 剩余参数必须放在最后
- log(keys) *************为一个数 组
5.扩展运算符(补充)
apply应用
对于Math.max 参数里面不支持Math.max([param1,param2]) 也就是数组
但是它支持Math.max(param1,param2,param3…),所以可以根据刚才apply的那个特点来解决
ES5 写法:::::::::::::::::::::::::::::;::::::::var max=Math.max.apply(null,array),这样轻易的可以得到一个数组中最大的一项
(apply会将一个数组装换为一个参数接一个参数的传递给方法)
第一个参数为什么是null:
这块在调用的时候第一个参数给了一个null,这个是因为没有对象去调用这个方法,
我只需要用这个方法帮我运算,得到返回的结果就行,.所以直接传递了一个null过去
6.箭头函数和this指向的注意事项
let getObj=id =>{
return{
id:id,
name:'heihei'
}
}
简洁版:
let getObj1=id =>({
id:id,
name:'heihei'
})
变为({})用于输出对象
箭头函数没有this的指向,箭头函数内部的this值只能通过查找作用域链来确定。this函数作用域内,逐级往上找。(一旦使用箭头函数,当前不存在作用域链)
// 如果箭头函数被一个非箭头函数所包括,那么this的值与该函数的所属对象相等,否则是全局的window对象(按作用域往上找当前对象)
下图会报错,因为这个this的指向为window全局对象
注意:使用箭头函数,函数内就没有argument参数(因为没有作用域链)
- 箭头函数不能使用 new 关键字来实例化对象,function 函数也是一个对象,但是箭头函数不是一个对象,它就是一个表达式。
- 报错
7. 解构赋值(两边类型要相同)
完全解构:
不完全解构:剩余运算符
默认值解构和数组解构::注意两边的对象类型要相同
9. Symbol类型
如何获取声明的Symbol类型的数据,下面为两种方法,一般不调用(了解即可)
10. Map 和 Set 方法
weakSet的详细参考博客:WeakSet的使用_mb5fdb0f269f12c的技术博客_51CTO博客
map的用法:
let map = new Map(); // set() 设置值 map.set('name', '张三'); map.set('age', '20'); console.log(map); // 输出 { 'name' => '张三', 'age' => '20'} // 键和值可以是任意类型 map.set(['a', [1, 2, 3]], 'hello'); // get() 获取值 console.log(map.get('name')); //张三 // has() 校验某个值是否在 map 中 console.log(map.has('name')); //true // delete() 删除值 map.delete('name'); // clear() 清除所有值 map.clear();
上图输出结果:
11. 数组的扩展方法
JavaScript 中 call()、apply()、bind() 的用法 | 菜鸟教程
// Array.from()方法用于将伪数组转为真正的数组
function add() {
// ES5 的写法,不宜阅读
var arr1 = [].slice.call(argumets); // [1, 2, 3]
console.log(arr1);
// ES6 的写法
let arr2 = Array.from(argumets); // [1, 2, 3]
console.log(arr2);
}
add(1, 2, 3);
// 方法二:使用扩展运算符, 将伪数组转为真正的数组
// querySelectorAll()方法返回的是一个类似数组的对象
let lis = document.querySelectorAll('li');
console.log([...lis]);
// Array.from()方法还可以接受第二个参数,对每个元素进行处理
let lis = document.querySelectorAll('li');
let names2 = Array.from(lis, s => s.textContent);
console.log(names2);
上述代码的返回结果:
for of 循环_KeplerMartin的博客-CSDN博客_for of循环 -----------Es6中的一些for循环区别
14 Iterator(遍历器)
15.生成器
//15生成器 主要解决异步操作 //使用场景:为不具备interator接口的对象提供便利操纵 //一是,function关键字与函数名之间有一个星号 * ;二是,函数体内部使用yield表达式 表达式 function* func() { console.log('star'); yield '暂停一下'; console.log('第二下star'); yield '暂停结束' } //返回一个遍历器对象 let o = func() console.log(o, '15生成器'); console.log(o.next()); console.log(o.next()); //总结:generator函数是分段执行的,yield语句是暂停执行,而next()是恢复执行 //15.2生成器 // 生成器函数:function关键字与函数名之间有一个星号 * ;函数体内部使用yield表达式 function* add3() { console.log('start'); // 这里的 x 不是 yield '2' 的返回值,它是下一个 next()调用恢复执行时传入的参数值 let x = yield '2'; // yield 暂停执行标志 console.log('one:' + x); let y = yield '3'; // yield 暂停执行标志 console.log('two:' + y); return x + y; } // 返回一个遍历器对象 let fn = add3() // next() 恢复执行标志 console.log(fn.next()); // start {value: '2', done: false} // 当 next() 传入参数时,该参数就会被当作上一个 ***(上一个 上一个)yield 表达式的返回值 ,即 x = 20, y = 30 console.log(fn.next(20)); // one:20 {value: '3', done: false} console.log(fn.next(30)); // two:30 {value: '50', done: true} //15.3 生成器的应用 const obj3 = { name: 'xxiao', age: 15 } console.log(obj3, '查看有没有symbol.iteration接口'); //没有这个迭代器接口啊 //15.4 Generator 生成器函数举例 function* objectEntries(obj4) { // 获取对象的所有 key 保存到数组 [name, age] const propKeys = Object.keys(obj4); for (const propkey of propKeys) { yield [propkey, obj4[propkey]] //propkey中保存着obj4的键:name和age;obj[propkey]为相对应的值 } } const obj4 = { name: '牛肉粉', age: 18 } // 把 Generator 生成器函数赋值给对象的Symbol.iterator属性, 为该对象加上遍历器接口 obj4[Symbol.iterator] = objectEntries; console.log(obj4); // objectEntries(obj4) 等价于 obj4[Symbol.iterator](obj4) for(let [key,value] of objectEntries(obj4)){ console.log(`${key}:${value}`); }
16 生成器应用
$.ajax({
url:'https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976',
method:'get',
success(res){
console.log(res);
}
})
//16.1 利用生成器将同步请求变为异步请求
function *main(){ //生成器定义函数
let res = yield request('http://d1.weather.com.cn/dingzhi/101230201.html?_=" + DateTime.Now.GetDateTimeToLongTimeStamp()')
console.log(res);
//执行后续请求一系列操作
}
let ite=main(); //定义生成器指代名称
ite.next();
function request(url){ //定义request方法
$.ajax({
url,
method:'get',
success(res){
ite.next(res); //c此操作将成功回调返回的结果赋值给main中的res
}
})
}
17 promise
- 简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果
- Promise 是一个对象,Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。axios 的内部实现原理就是通过 Promise 实现的
- Promise对象有以下两个特点:
- 对象的状态不受外界影响。有三种状态:pending(进行中)、fulfilled(成功)和rejected(失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态
- 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为resolved和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果
- Promise对象是一个构造函数,用来生成Promise实例,带有一个回调函数,回调函数的两个参数是 resolve(成功) 和 reject(失败),这两个参数他们也是函数。
- then方法的第一个参数是resolved状态的回调函数,第二个参数是rejected状态的回调函数,它们都是可选的。
### 实例化
Promise构造函数接收一个函数作为参数,也就是回调函数;该函数的两个参数分别是resolve和reject。resolve作为成功的回调函数,reject作为失败的回调函数。Promise对象代表一个异步操作有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。最后返回resolved(已定型)结果。
### 2.实例方法
定义在Promise.prototype中的方法,通过Promise实例可以直接调用
then() 状态由pending变为fulfilled的时候也就是异步操作成功之后执行该回调函数
参数:回调函数,回调函数的参数为resolve函数传递过来的值
返回值:返回一个新的Promise实例对象,因此可以使用链式调用
catch() 由pending变为rejected的时候执行该回调函数也就是异步失败之后执行该回调函数
参数:回调函数,回调函数的参数为reject函数传递过来的值
返回值:返回一个新的Promise实例对象,因此可以使用链式调用
finally()无论异步操作执行成功失败与否,都会执行该回调
参数:回调函数
返回值:返回一个新的Promise实例对象
18-19 all(), race()
//18 自己封装ajax 自己封装getJson方法
//then里面传了两个回调函数,第一个代表成功之后的回调,第二个代表失败之后的回调,分别代表resolve()和reject()
console.log('18---------------');
const getJson = function (url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = handler;
xhr.resposeType = 'json';
xhr.setRequestHeader('Accept', 'application/json');
xhr.send();
function handler() {
if (this.readyState === 4) {
if (this.status === 200) {
resolve(this.respose);
} else {
reject(new Error(this.statusText))
}
}
}
})
}
getJson('https://free-api.heweather.net/s6/weather/now?location=beijing&key=4693ff5ea653469f8bb0c29638035976')
.then((data) => {
//then里面传了两个回调函数,第一个代表成功之后的回调,第二个代表失败之后的回调,分别代表resolve()和reject()
console.log(data); //data相当于promise中成功执行之后返回的resolve中的返回值
}, (error) => {
console.log(error);
})
//19 promise 的其他方法 resolve 能将现有的任何对象转换为promise对象
let p = Promise.resolve('成功值')
//等价于let p = new Promise(resolve=>resolve('foo'))
p.then(val => {
console.log(val, '19---------'); //输出成功值 19---------
})
//小应用 race()的应用
// 请求图片资源
function requestImg(imgSrc) {
return new Promise((resolve, reject) => {
const img = new Image();
// 加载图片资源
img.onload = function () {
resolve(img);
}
img.src = imgSrc;
});
}
//延时函数,用于给请求计时
function timeout() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('图片请求超时'));
}, 3000);
});
}
// Promise.race()接受一个包含多个promise对象的数组(数组数组),只要有一个完成,就执行success
// 如果3s 之内加载完成就执行 then 方法, 3s 之后还没加载完成就执行 catch 方法
Promise.race([requestImg('https://i2.hdslb.com/bfs/face/59a2cb990fde5e2cd289c3305450664b462da341.jpg@240w_240h_1c_1s.webp'), timeout()]).then((data) => {
console.log(data);
document.body.appendChild(data);
}).catch((err) => {
console.log(err);
});