promise 是ES6新增异步解决方案
Promise generator ===> ES7 async/await
Promise(承诺) 表示未来的某个时间一定会返回一个结果
Promise 是一个容器,里面包裹了一些异步操作,它表示一个预计会在未来完成的异步操作
PromiseState(promise状态) pending(进行中) fulfilled(已成功) rejected(已失败)
Promise状态变化pending =>fulfilled 或者 pending=>rejected 不可逆的,而且一旦执行成功状态就会凝固 不会在发生其他变化了
Promise实例上 有三个api
then(resolve=>{},reject=>{}) 方法中有两个回调函数 分别表示成功后的回调 和失败后的回调
catch(err=>{}) 在创建或者使用promise的时候,如果代码报错那么会自动的走then.reject 如果在then中没有reject回调,会在catch中进行错误捕获, catch方法也会捕获在then方法中发生任何错误
finally(()=>{}) 无论promise执行成功或者失败,也无论catch方法是否执行, 最终finally都会执行
1.一旦promise创建成功就会立即执行(new Promise())
console.log(1); let p1=new Promise((resolve,reject)=>{ resolve('1') //成功后的回调 reject('2')//失败后的回调 console.log(2); }) console.log(p1); //Promise p1.then((resolve)=>{//异步操作 // resolve 成功后的结果 console.log(3); console.log("resolve 成功后的结果",resolve);//1 如果成功则不会走reject },(reject)=>{ // reject失败后的结果 console.log("reject 失败后的结果",reject);//2 }) console.log(4);
上述代码中他们的打印数字顺序是1243,代码从上往下执行,promise里面是同步的,它的then方法是异步的所以放在了最后。
promise的手动报错的方法: throw new Error("手动报错"),打上这个代码手动报错后就会走reject或者catch方法
2.promise错误捕获 catch
在创建或者使用promise的时候,如果代码报错那么会自动的走then.reject 如果在then中没有reject回调,会在catch中进行错误捕获, catch方法也会捕获在then方法中发生任何错误
let p1=new Promise((resolve,reject)=>{ if(1<0){ resolve(1) }else{ reject(2) } }) p1.then((resolve)=>{ throw new Error('手动报错') console.log('resolve 成功后的结果', resolve); }).catch((err)=>{ console.log("catch err==>",err); }) //返回结果是:catch err==> 2
3.promise.finally方法
无论promise执行成功或者失败,也无论catch方法是否执行, 最终finally都会执行
let p1=new Promise((resolve,reject)=>{ if(1>0){ throw new Error('手动报错') resolve(1) }else{ reject(2) } }) p1.then((resolve)=>{ console.log('resolve 成功后的结果',resolve); },(reject)=>{ console.log("reject 失败后的结果",reject); }).catch(err=>{ console.log("catch err==>",err); }).finally(()=>{ console.log("finally fin===>"); }) //此时会走reject打印:'reject 失败后的结果 Error: 手动报错' //同时会走finally打印: finally fin===>
1.Promise.resolve
2.Promise.reject
3.Promise.all 全部 :Promise.all方法 参数是多个promise对象组成的数组, 返回值是一个新的promise对象
如果参数中的promise对象都成功就正常返回,并且promiseAll方法中的每一个promise都是并行状态,当全部完成之后就会自动的调用promise.all().then()方法.
如果参数中的promise对象有任意一个没有正常返回,那么整个pAll都会认为是失败的,并且把失败的这个promise对象的返回值直接输出 其他的就不会在继续执行了
let p1 = new Promise((resolve, reject) => { setTimeout(() => {//模拟异步 resolve("p1") }, 1000) }); let p2 = new Promise((resolve, reject) => { setTimeout(() => {//模拟异步 resolve("p2") }, 5000) }); let p3 = new Promise((resolve, reject) => { setTimeout(() => {//模拟异步 reject("p3") }, 2000) }); let pAll = Promise.all([p1, p2, p3]); pAll.then( resolve => { console.log("成功后的回调",resolve);//"成功后的回调",["p1", "p2", "p3"] }, reject => { console.log("失败后的回调",reject); }) //由于p3里面返回的是失败的,all方法就会走reject打印:失败后的回调 p3 //如果都是成功则all方法会走resolve打印:成功后的回调 (3) ["p1", "p2", "p3"]
4.Promise.race
Promise.race方法返回的也是一个promise对象, race方法谁先有结果就返回谁,无论成功还是失败(成功的就走resolve,失败就会在reject中返回)
let p1 = new Promise((resolve, reject) => { setTimeout(() => {//模拟异步 reject("p1") }, 1000) }); let p2 = new Promise((resolve, reject) => { setTimeout(() => {//模拟异步 resolve("p2") }, 5000) }); let p3 = new Promise((resolve, reject) => { setTimeout(() => {//模拟异步 resolve("p3") }, 2000) }); let pRace = Promise.race([p1, p2, p3]); pRace.then( resolve => { console.log("成功后的回调",resolve);//成功后的回调 p1 }, reject => { console.log("失败后的回调",reject);//失败后的回调 p1 }) //rece方法是谁先有结果先返回谁,由于p1时间最短所以会走reject打印:失败后的回调 p1
1.promise.all方法
需求:有三张图片 ,如果这三张图片都加载完成 那么就直接显示到页面中 否则就不展示
var imgSrc1 = 'https://desk-fd.zol-img.com.cn/t_s1920x1200c5/g5/M00/0B/0D/ChMkJlvfvrWIcWxTAAVwJpEWx6kAAs9wwEITscABXA-520.jpg' var imgSrc2 = 'https://desk-fd.zol-img.com.cn/t_s1920x1080c5/g5/M00/0B/0D/ChMkJlvfwAeIRMZcAAVF6izrBzIAAs9xAMyo3YABUYC824.jpg' var imgSrc3 = 'https://desk-fd.zol-img.com.cn/t_s1920x1080c5/g5/M00/05/06/ChMkJ1xJk6mIBBi-AAX3ilTYbAcAAujyAEja8wABfei891.jpg' var imgBox = document.getElementById('imgBox') var loadImg = (arg) => { return new Promise((resolve,reject)=>{ // 配置定时器,用来看管是否在一定时间内完成,如果没有就报超时 setTimeout(() => { reject('超時') }, 5000); // 如果一定时间内完成会走以下代码: // 创建一个img标签 var img = document.createElement('img') // /当图片标签获得scr属性的时候,图片就开始被加载 img.setAttribute('src',arg) // 当图片加载完成会触发这个onload回调函数 img.onload = () => { resolve(img) } }) } // 使用promise的api:all方法,调用三次加载图片函数 //如果都成功了,那么会返回成功后promise的resolve方法,如果有一个失败就会返回失败 Promise.all([loadImg(imgSrc1),loadImg(imgSrc2),loadImg(imgSrc3)]).then(resolve=>{ // resolve==> [图片1,图片2,图片3] for(var i = 0 ; i < resolve.length ; i++ ){ // 将返回的img标签追加到元素中 imgBox.appendChild(resolve[i]) } }).catch(err=>{ alert(err) })
2.promise.race方法
需求 有一张图片 ,当这张图片的加载时间超过1s的时候,就不去加载了,并且在页面中显示加载超时,如果1s内完成了加载,那么就在页面中进行展示
var loadingImg = (arg) => { var src = arg || 'https://desk-fd.zol-img.com.cn/t_s1920x1080c5/g5/M00/05/06/ChMkJ1xJk6mIBBi-AAX3ilTYbAcAAujyAEja8wABfei891.jpg' return new Promise((reslove,reject)=>{ var img = document.createElement('img')//创建标签 img.setAttribute('src',src)//给img标签添加src属性 img.onload = () => {//图片加载完成会触发这个onload回调函数 reslove(img) } }) } //设置timeOut函数方法 var timeOut = () => { //设置一个定时器 return new Promise((reslove,reject)=>{ setTimeout(()=>{ reject('图片加载超时') },2000) }) } //使用promise.race方法来判断成功与否,如果2秒内成功就显示照片,否则显示图片超时 Promise.race([loadingImg(),timeOut()]).then(res=>{ document.body.appendChild(res) }).catch(err=>{ alert(err) })