# ES6
# Promise
# 基础使用
Promise意为允诺,虽然从现在开始努力(新建的Promise立即执行),但以后才能知道结局(成功或失败)。通常,Promise用于包装异步行为,即事件a完成后执行事件b,如果没有这种同步机制,就无法写出a->b的逻辑。
new Promise((resolve,reject)=>{
setTimeout(()=>{console.log('after 1000ms')},1000);
resolve();
})
//after 1000ms
# Promise.prototype.then()
我们注意到Promise接受了一个函数,而这个函数接受了两个参数resolve和reject,这俩是内置的函数,触发它们可以改变Promise的状态(从pending到fulfillment或者rejection)。
状态改变会继续执行then方法中的函数:then接受两个函数,一个在resolve时触发,另一个在reject时触发。resolve或reject执行后,之后的代码仍然会执行并且先于then。
then支持链式调用,也就是说then的返回值仍然可以用then,无论返回原始值、抛出错误还是返回Promise最终都返回Promise,具体情况参考下表(很好理解,不用记)。
new Promise((resolve,reject)=>{
if(Math.random()>0.5){
resolve('suc');
}else{
reject('err');
}
}).then((resolve)=>{
console.log(resolve)
},(reject)=>{
console.log(reject)
})
//可能输出suc或err
# Promise.prototype.catch()
如果Promise的状态变成reject,不仅会触发then 方法,也会触发catch方法。
从实现的角度上讲,该方法与使用then的第二个参数完全相同。
new Promise((resolve,reject)=>{
reject('err');
}).catch((err)=>{
console.log(err)
})
//err
# 关于throw
通常throw会触发then的第二个方法和catch。但在异步函数中调用throw无效(同步函数内有效),在resolved()触发后throw无效。
# Promise.all()
通常接受一个Promise数组,返回一个Promise,都完成时返回的Promise变fullfillment,有一个错误即变reject。如果打算在网页加载时显示loading,使用Promise.all响应图片的onload是个好主意。
实际上Promise.all接受所有的可迭代对象,如果传入的对象为空,返回fullfillment的Promise;如果对象不包含Promise,则返回异步完成的Promise(与前者的区别涉及Event-loop,对于异步完成的Promise,之后的同步代码会认为其处于pending状态);其他情况返回pending的Promise并根据执行情况转换状态。
# Promise.race()
和Promisel.all()相近,一旦其中一个Promise状态改变结果即确定(由最早改变状态的Promise决定)。用途可能在从不同路径请求相同资源,选择较快的那一个。
# Promise.resolve()
手动创建已经resolve的Promise。接受一个参数value,返回的Promise已执行resolve(value)。value如果是Promise,则直接返回此Promise;如果是带有then方法的对象let obj = {then:(res,rej)=>{res()}}
,返回的Promise相当于已执行了then方法new Promise(obj.then)
。
# thenable
指具有then方法的对象,可以作为参数传给Promise。
# Promise.reject()
手动创建已经reject的Promise。接受一个参数作为reject的原因(可以是Error对象)。
# Promise.prototype.allSettled()
还处于Draft。allSettled接受一个Promise数组,等待所有的Promise都被resolve或reject,它返回一个Promise,其中传递了每一个Promise的status。
# generator 生成器 ✏️
# 模板字符串/模板字面量
用反引号``表达的字符串,可以在其中使用${expression}
表达式。以表达式开头的模板字符串被称为带标签的模板字符串(通常是函数)。
模板字符串支持多行字符串、表达式与嵌套(需要在表达式内)。
let total = 10;
let str = `She has ${total} apples.`
let str1 = `He said that ${`She has ${total} apples`}`
# 带标签的模板字符串
字符串前的函数接收了字符串与表达式,前者以数组的形式,后者以多个参数的形式传递,通过函数返回处理过后的值。
let dict=['一个顶俩','救过不给']
let harmony = function(str,exp1,exp2){
if(exp1=="一个顶俩"){
exp1="****"
}
if(exp2=="救过不给"){
exp2="****"
}
return str[0]+exp1+exp2+str[2]
}
let str1 =harmony`我发送了两个红包${dict[0]}${dict[1]},请用新版QQ查看`
//str1
//我发送了两个红包********,请用新版QQ查看 :str数组有3个元素,str[1]=='' :str数组还有特殊的raw方法,可以获得未转义的字符串
//dict
//[ '一个顶俩', '救过不给' ] :不改变原表达式
# 类与对象
# 转译
# babel
# polypill
# traceur
# 遍历器 Iterator
Iterator提供了一个通用的接口,只要有此接口就可以用for(let item of obj)
完成遍历。遍历器除了访问每一个成员,还决定访问的顺序。
# 解构赋值
在扩展运算符中,我们已经了解构赋值的用法。也许它应该叫模式匹配。
# 数组形式的解构赋值
let [a,b,c] = [1,2,3]
//a==1 b==2 c==3
let [d,[e,f],g] = [4,[5,6],7]
//d==4 e==5 f==6 g==7 不写f也不会报错
let [d,[e,f=10],g] = [4,[5],6]
//d==4 e==5 f==10 g==6 f等于默认值
右边的对象不具有Iterator接口会导致报错,而具有Iterator接口的对象(即使不是数组)不会报错。
# 对象形式的解构赋值
let {x,y} = {x:100,y:50};
//x==100 y==50
let {random} = Math;
let {log} = console;
//random==Math.random log==console.log
let {food:dinner} = {food:"pork"};
//dinner=="pork"
let {obj:{day,night}} = {obj:{day:'0',night:'12'}}
//day==0 night==12
let obj={};
Object.setPrototypeOf(obj,{size:67});
let {size} = obj;
//支持获取原型上的属性
let {xx=0,y:yy=83} ={}
//xx=0 yy=83 使用默认值
# 函数参数形式的解构赋值
在函数参数中,每一个参数都可以解构。
let f1=([a,b],[c])=>a+b+c;
f1([1,2],[3]);
//6
let f2=({a,b=10},{c=5}={})=>a+b+c;
f2({a:10});
//25
# 箭头函数
()=>
_=>
# 参考
TIP
# Promise.then()的返回值
当一个Promise
完成(fulfilled)或者失败(rejected),返回函数将被异步调用(由当前的线程循环来调度完成)。具体的返回值依据以下规则返回:
如果then中的回调函数返回一个值,那么then返回的Promise将会成为接受状态,并且将返回的值作为接受状态的回调函数的参数值。
如果then中的回调函数没有返回值,那么then返回的Promise将会成为接受状态,并且该接受状态的回调函数的参数值为 undefined。
如果then中的回调函数抛出一个错误,那么then返回的Promise将会成为拒绝状态,并且将抛出的错误作为拒绝状态的回调函数的参数值。
如果then中的回调函数返回一个已经是接受状态的Promise,那么then返回的Promise也会成为接受状态,并且将那个Promise的接受状态的回调函数的参数值作为该被返回的Promise的接受状态回调函数的参数值。
如果then中的回调函数返回一个已经是拒绝状态的Promise,那么then返回的Promise也会成为拒绝状态,并且将那个Promise的拒绝状态的回调函数的参数值作为该被返回的Promise的拒绝状态回调函数的参数值。
如果then中的回调函数返回一个未定状态(pending)的Promise,那么then返回Promise的状态也是未定的,并且它的终态与那个Promise的终态相同;同时,它变为终态时调用的回调函数参数与那个Promise变为终态时的回调函数的参数是相同的。