1.Promise
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===>
2.Promise的API:应用程序接口
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
3.PromiseAPI和应用
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)
})