感恩阮一峰老师的ECMAScript 6 入门,其他知识正在陆续学习中,会在该文章中陆续添入。
promise
将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
含义:简单说就是一个容器,里面包含着一个未来可能结束的事件的结果
特点:
1.对象状态不受外界影响:pending进行中 fulfilled成功 rejected失败。只有异步操作的结果可以决定当前是哪一种状态其他操作不可以---promise的由来
2.状态一经改变就无法再变:只有pending-->fulfilled 和pending-->rejected两种可能,只要状态发生改变就不会再变,任何时候都可以得到这个结果。
Promise对象是一个构造函数,接收一个函数作为参数...新建后立即执行
Promise实例生成后可以用then方法分别指定resolved和rejected状态的回调函数
注:
1.立即resolved的Promise总是在本轮事件循环的末尾执行,总是晚于本轮事件循环的同步任务
2.then方法返回的是一个全新的Promise实例所以可以进行链式调用,指定一组按次序调用的回调函数。
截取几个常用方法介绍:
Promise.catch() | 就是.then(null,function(error){})建议使用这种方法的原因是:catch还可以捕捉前面的then方法执行中的错误;如果都写在一个then中显然是不会捕获 |
Promise.all() | 将多个Promise实例包装成一个新的Promise实例,只有这些Promise都resolved才会resolved只要有一个rejected就rejected。但是实例里面如果有catch 那么最后整个实例的catch不会捕获到错误所以是resolved状态 |
Promise.race() | 和all方法类似但是只要有一个实例状态改变,最终状态就用它 |
Promise.resolve()可以将一个对象变成Promise对象(立即resolved的Promise总是在本轮事件循环的末尾执行,总是晚于本轮事件循环的同步任务) | 参数是一个Promise实例,不做修改原封不动的返回实例 |
参数是一个具有then方法的对象,会将该对象转变成Promise对象,然后立即执行then方法 | |
不是对象或者不含then方法的对象。返回一个resolved状态的新Promise对象 | |
不带参数返回一个resolved状态的Promise对象 | |
Promise.reject() | 返回状态为rejected状态的Promise实例 |
promise缺点:
- 无法取消Promise,一旦新建它就会执行,无法中途取消
- 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部
- 当处于Pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)
Iterator
概念:Iterator是一种机制,为不同的数据结构提供统一的简单的访问接口;Iterator主要是供for..of使用
注:es6之后我们有了四种表示集合的数据结构:Array,Object,Set(类似于数组),Map(类似于对象)
使用:每次调用指针对象的next方法都返回数据结构的当前成员的值value和一个表示是否遍历结束的布尔值done。
ES6默认的Iterator接口部署在数据结构的Symbol.iterator属性上,只要一个数据结构具有这个属性就认为是可遍历的。(Array Map Set String 函数的arguments对象 NodeList对象 TypedArray对象)。调用Iterator接口即调用Symbol.iterator方法:解构赋值、扩展运算符、yield*。由于数组的遍历会调用遍历器接口所以任何接收数组作为参数的场合都调用了Iterator接口 像 for ...of Array.from Map() WeakMap() Set() WeakSet() Promise.all() Promise.race()
简单实用:
let arr=[1,2,3];
let ite=arr[Symbol.iterator]();
console.log(ite)
console.log(ite.next());
console.log(ite.next());
console.log(ite.next());
console.log(ite.next());
运行结果:
Genenrator函数
是Iterator接口(或者说实现Symbol.iterator方法)的一种方式。G函数返回一个部署了Iterator接口的遍历器对象。每次调用遍历器对象的next方法,就会返回一个有着value和done两个属性的对象。value属性表示当前的内部状态的值,是yield语句后面那个表达式的值;done属性是一个布尔值,表示是否遍历结束。
(1)遇到yield语句,就暂停执行后面的操作,并将紧跟在yield后面的那个表达式的值,作为返回的对象的value属性值;
(2)下一次调用next方法时,再继续往下执行,直到遇到下一个yield语句;
(3)如果没有再遇到新的yield语句,就一直运行到函数结束,直到return语句为止,并将return语句后面的表达式的值,作为返回的对象的value属性值;
(4)如果该函数没有return语句,则返回的对象的value属性值为undefined。
需要注意的是,yield语句后面的表达式,只有当调用next方法、内部指针指向该语句时才会执行,因此等于为JavaScript提供了手动的“惰性求值”(Lazy Evaluation)的语法功能。
- yield句本身没有返回值(返回undefined)。next方法可以带一个参数,该参数就会被当作上一个yield语句的返回值。
- for of循环可以自动遍历G函数yield后面的那个表达式的值,不需要调用next方法。
- yield*一个可迭代对象,就相当于把这个可迭代对象的所有迭代值分次 yield 出去。
简单测试:
function *foo() {
yield 1;
yield 2;
return 3;
}
for (let v of foo()) {
console.log(v);//一旦next方法返回对象的done为true 那么for of循环就会终止,且不包含该返回对象。可以看运行结果
}
运行结果:
generator函数实现Fibonacci sequence:
function *fib(){//1 1 2 3
let [pre,cur]=[0,1];
let i=0;
while(i<10){
[pre,cur]=[cur,pre+cur];
i++;
yield pre;
}
}
for(let v of fib()){
// if (v>50) {
// break;
// }
console.log(v);
}
运行结果:
Async函数
generator函数的语法糖。*-->async yield-->await 实现原理即:将G函数和自动执行器包在一个函数里。
优点:
1.内置执行器不用调用next方法
2.更好的语义说明,async表示异步操作 await表示后面的表达式需要等待结果
3.更广的适用性:await后面可以是原始类型值或promise对象。await命令后是一个Promise对象。如果不是,会被转成一个立即resolve的Promise对象。
4.返回promise对象,可以用then方法添加回调函数。
async函数实现Fibonacci sequence:
async function fib0(){//1 1 2 3
let [pre,cur]=[0,1];
let i=0;
let res=[]
while(i<10){
[pre,cur]=[cur,pre+cur];
i++;
await res.push(pre);
}
return res;
}
fib0().then((result)=>{
console.log(`async函数:${result}`)
}).catch((err)=>{console.log(err)});
运行结果: