解决的问题:回调地狱segmentfault
Promise规范:promise
promise有三种状态,等待(pending)、已完成(fulfilled/resolved)、已拒绝(rejected).Promise的状态只能从“等待”转到“完成”或者“拒绝”,不能逆向转换,同时“完成”和“拒绝”也不能相互转换.异步
promise 必须提供一个 then方法以访问其当前值、终值和据因。promise.then(resolve, reject),resolve 和 reject都是可选参数。若是 resolve 或reject 不是函数,其必须被忽略.async
then 方法必须返回一个 promise 对象.函数
使用:code
实例化promise对象须要传入函数(包含两个参数),resolve和reject,内部肯定状态.resolve和reject函数能够传入参数在回调函数中使用.
resolve和reject都是函数,传入的参数在then的回调函数中接收.对象
var promise = new Promise(function(resolve, reject) { setTimeout(function(){ resolve('好哈哈哈哈'); }); }); promise.then(function(val){ console.log(val) })
then接收两个函数,分别对应resolve和reject状态的回调,函数中接收实例化时传入的参数.get
promise.then(val=>{ //resolved },reason=>{ //rejected })
catch至关于.then(null, rejection)
当then中没有传入rejection时,错误会冒泡进入catch函数中,若传入了rejection,则错误会被rejection捕获,并且不会进入catch.此外,then中的回调函数中发生的错误只会在下一级的then中被捕获,不会影响该promise的状态.generator
new Promise((resolve,reject)=>{ throw new Error('错误') }).then(null,(err)=>{ console.log(err,1);//此处捕获 }).catch((err)=>{ console.log(err,2); }); // 对比 new Promise((resolve,reject)=>{ throw new Error('错误') }).then(null,null).catch((err)=>{ console.log(err,2);//此处捕获 }); // 错误示例 new Promise((resolve,reject)=>{ resolve('正常'); }).then((val)=>{ throw new Error('回调函数中错误') },(err)=>{ console.log(err,1); }).then(null,(err)=>{ console.log(err,2);//此处捕获,也可用catch });
二者不等价的状况:
此时,catch捕获的并非p1的错误,而是p2的错误,回调函数
p1().then(res=>{ return p2()//p2返回一个promise对象 }).catch(err=> console.log(err))
一个错误捕获的错误用例:
该函数调用中即便发生了错误依然会进入then中的resolve的回调函数,由于函数p1中实例化promise对象时已经调用了catch,若发生错误会进入catch中,此时会返回一个新的promise,所以即便发生错误依然会进入p1函数的then链中的resolve回调函数.
function p1(val){ return new Promise((resolve,reject)=>{ if(val){ var len = val.length;//传入null会发生错误,进入catch捕获错误 resolve(len); }else{ reject(); } }).catch((err)=>{ console.log(err) }) }; p1(null).then((len)=>{ console.log(len,'resolved'); },()=>{ console.log('rejected'); }).catch((err)=>{ console.log(err,'catch'); })
Promise回调链:
promise可以在回调函数里面使用 return 和 throw, 因此在then中能够return出一个promise对象或其余值,也能够throw出一个错误对象,但若是没有return,将默认返回 undefined,那么后面的then中的回调参数接收到的将是undefined.
function p1(val){ return new Promise((resolve,reject)=>{ val==1?resolve(1):reject() }) }; function p2(val){ return new Promise((resolve,reject)=>{ val==2?resolve(2):reject(); }) }; let promimse = new Promise(function(resolve,reject){ resolve(1) }) .then(function(data1) { return p1(data1)//若是去掉return,则返回undefined而不是p1的返回值,会致使报错 }) .then(function(data2){ return p2(data2+1) }) .then(res=>console.log(res))
generator函数使用:
一、分段执行,能够暂停
二、能够控制阶段和每一个阶段的返回值
三、能够知道是否执行到结尾
function* g() { var o = 1; yield o++; yield o++; } var gen = g(); console.log(gen.next()); // Object {value: 1, done: false} var xxx = g(); console.log(gen.next()); // Object {value: 2, done: false} console.log(xxx.next()); // Object {value: 1, done: false} console.log(gen.next()); // Object {value: undefined, done: true}
generator和异步控制:
利用Generator函数的暂停执行的效果,能够把异步操做写在yield语句里面,等到调用next方法时再日后执行。这实际上等同于不须要写回调函数了,由于异步操做的后续操做能够放在yield语句下面,反正要等到调用next方法时再执行。因此,Generator函数的一个重要实际意义就是用来处理异步操做,改写回调函数。
用法:
async 表示这是一个async函数,await只能用在这个函数里面。
await 表示在这里等待异步操做返回结果,再继续执行。
await 后通常是一个promise对象
示例:async用于定义一个异步函数,该函数返回一个Promise。
若是async函数返回的是一个同步的值,这个值将被包装成一个理解resolve的Promise,等同于return Promise.resolve(value)。
await用于一个异步操做以前,表示要“等待”这个异步操做的返回值。await也能够用于一个同步的值。
let timer = async function timer(){ return new Promise((resolve,reject) => { setTimeout(() => { resolve('500'); },500); }); } timer().then(result => { console.log(result); //500 }).catch(err => { console.log(err.message); }); //返回一个同步的值 let sayHi = async function sayHi(){ let hi = await 'hello world'; return hi; //等同于return Promise.resolve(hi); } sayHi().then(result => { console.log(result); });