这里是参考阮一峰大牛编写的《ECMAScript 6 入门教程》进行部分总结
一、promise对象
1、Promise 的含义
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大
2. 创建promise对象
创建promise对象时,需要传递一个函数作为参数,作为参数需要传递两个回调函数,resolve、reject作为参数,这两个参数可以被调用
resolve成功时的回调函数
reject失败时的回调函数
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
3. promise被创建完毕之后,会立即执行
let promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve();
});
promise.then(function() {
console.log('resolved.');
});
console.log('Hi!');
// Promise
// Hi!
// resolved
4. Promise有三种状态
进行中 pending
成功 fullfilled
失败 rejected
pending----->成功 主动调用resolve
pending---->失败 主动调用reject方法
5.then(然后)方法
then方法可以接收两个参数,这两个参数都是函数,
第一个参数(函数):成功时的回调
第二个参数(函数):失败时的回调
then方法默认会返回一个新的promise对象
6.catch(捕获)方法
能够接收一个失败的回调(参数是一个函数,promise状态失败时,会触发这个函数)
7.接收失败信息
根据以上两点可以总结出两种接收失败信息的方法
方法一:使用then方法的第二个参数
方法二:使用catch方法的参数
catch可以捕获到代码中的异常
推荐使用catch来接收失败的信息
8.链式调用
p.then().then().then()…
then方法的第一个参数,成功时的回调函数,分两种情况:
第一种情况:返回了一个普通的数据(非promise),这个值会作为参数传递给下一个then的成功回调
第二种情况:返回了一个promise,下一个then的执行,取决于这个promise状态的改变
二、iterator(迭代器、遍历器)
1. 概念和作用
它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。
Iterator 的作用有三个:
一是为各种数据结构,提供一个统一的、简便的访问接口;
二是使得数据结构的成员能够按某种次序排列;
三是 ES6 创造了一种新的遍历命令for…of循环,Iterator 接口主要供for…of消费。
iterator用来遍历集合类型,集合类型有:Array,Object,Set,Map
Array,Set和Map可以使用forEach来遍历(系统部署了iterator接口,所有可以用for…of…遍历)
Object使用for…in来遍历
2. 部署iterator接口
实际使用使用,需要在数据结构上部署默认的iterator接口;然后再通过next调用来使用。
在对象上部署iterator接口,如下例:
Array,Set和Map都默认具备iterator接口,默认接口叫做 Symbol.iterator
// 我们以对象为例,来给对象部署默认iterator接口
let obj = { name: "zhangsan", age: 22, address: "北京" };
// 部署默认接口 Symbol.iterator ;用来访问不同的数据接口,真正实现iterator的功效
obj[Symbol.iterator] = function () {
let keys = Object.keys(this); //[name,age,address]
let index = 0; //记录索引下标
return {
// 箭头函数
next: () => {
if (index < keys.length) {
let key = keys[index++];
return { value: this[key], done: false };
} else {
return { value: undefined, done: true };
}
}
};
};
// 访问默认的接口内容
let iterator = obj[Symbol.iterator]();
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());//undefined
总结:
1、过程:创建的是一个指针对象,这个对象指向的是结构中的起始位置,也就是说interator本质上就是一个指针对象,通过调用next(),第一次调用指向的是结构中的第一个成员,第二次调用指向就是结构中的第二个成员,一直到结构结束的位置;
2、返回值:返回的是对象,{value:值,done:false} done为false的时候,表示可以继续循环遍历,为true表示遍历结束{value:undefined,done:true}
3.for…of的使用
for…of是iterator的语法糖,所以部署了iterator接口的数据集合都可以使用for…of遍历
- for…of相比forEach和for…in的优势在哪里:
1、无法中途跳出forEach循环,break命令或return命令都不能奏效。
2、数组的键名是数字,但是for…in循环是以字符串作为键名“0”、“1”、“2”等等。
for…in循环不仅遍历数字键名,还会遍历手动添加的其他键,甚至包括原型链上的键。不安全
3、某些情况下,for…in循环会以任意顺序遍历键名。
总结:for…of适合遍历数组,for…in适合遍历对象
三、generator(生成器)
generator是一个函数,只不过这个函数的写法比较特殊,在function关键字和函数名之间有一个 * ,这样就构成一个generator生成器;
它不是普通的函数,它的调用不会立即执行;
调用后返回一个iterator遍历器,每次调用next则执行一步,直到调用结束。
return的返回可以立即结束iterator遍历器。
1. generator意义是什么?
generator内部是一个状态机,可以使用next调用返回多次结果;
也可以使用next传递参数给generator函数,来改变函数内部的执行逻辑。
generator内部支持yield表达式
,通过调用next,可以让generator内部的yield表达式执行;调用一次执行一次。
需要注意的是yield表达式没有返回值(返回undefined);
所以下一步的执行需要上一步执行结果的时候,可以使用next传递参数,如下:
function* pow(num) {
let first = yield Math.pow(num, 2);
let second = yield Math.pow(first, 2);
return Math.pow(second, 2);
}
let iterator = pow(2);
let { value: first } = iterator.next();
console.log(first);
let { value: second } = iterator.next(first);
console.log(second);
let { value: third } = iterator.next(second);
console.log(third);
注意:
此时使用for…of不合适,因为没法传递参数
for (let iterator of pow(2)) {
console.log(iterator);
}
四、async和await(重点)
ES6在2017年引入async函数,能够使异步操作更加方便
async函数就是Generator函数的语法糖
async函数就是将Generator函数中*替换为async
使用await替代yield async …await就是基于promise的generator函数和yield的语法糖
1. async函数
- async是用来修饰函数
- async修饰函数是异步函数
- async函数的返回值是一个promise对象
- 该函数内部的return结果,会作为函数调用promise对象的resolve结果
2. await
- await必须要出现在async修饰的方法中,否则报错,也就说await不能单独使用
- await用来等待一个方法的执行,该方法可以是同步方法也可以是promise,一般用来等待promise的执行
- 通过使用async…await可以让以前的then或catch回调函数形式,变成同步的做法,让可读性更好
- await等待的是promise的resolve结果,如果promise的结果是reject,await会报错,它处理不了异常;需要借助try…catch或catch来捕获异常
- 不管promise是成功还是失败,await都会等待这个异步处理,只有当异步有成功或失败的结果,才执行后续代码
3. await-to-js
await to用来捕获异常信息,处理异常,因为使用try…catch的方式来处理异常不能直接指导报错的是那一句代码,使用后缀加catch的方法使得代码不优雅
function to(promise) {
return promise
.then(rst => {
//在ES6中只返回一句代码,return和大括号都可以省略
//这里就不做省略了,增加可读性
return [null, rst];
})
.catch(err => {
return [err,null];
});
}
备注:
上述代码的then和catch都有return返回,下一次的链式进入then还是进入catch?
这需要看return 的内容是否有异常或是否是错误;比如return [null,rst]或 return [err,null] ,下一次都会进入then;比如:throw new Error(‘错误’),下一次会进去catch