ES6新增异步解决方案。
是什么?
1.表示未来的某个时间一定会返回的一个结果
2.是一个容器,里面包裹了一些异步操作,它表示一个预计会在未来完成的异步操作
3.PromiseState(promise状态):
pending(进行中) fulfilled(已成功) rejected(已失败)
resolve作用:将Promise对象的状态从“未完成”变为“成功”( pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去
reject作用:将Promise对象的状态从“未完成”变为“失败”( pending 变为 rejected),在异步- 操作失败时调用,并将异步操作报出的错误,作为参数传递出去
4.Promise的状态变化:
pending =>fulfilled 或者 pending=>rejected
是不可逆的,一旦执行成功状态就会凝固 不会在发生其他变化了。
5.Promise 实例的三个api:
then(resolve=>{}, reject=>{}) 方法中有两个回调函数:
分别表示成功后的回调 和失败后的回调。
then的作用:是为 Promise 实例添加状态改变时的回调函数
then方法的第一个参数是resolved状态的回调函数代表fulfilled(成功),第二个参数是rejected状态的回调函数rejected(失败),它们都是可选的。
.then()返回一个新的Promise实例,所以它可以链式调用
当前面的Promise状态改变时,.then()根据其最终状态,选择特定的状态响应函数执行。
catch(err=>{}) 在创建或者使用promise的时候,如果代码报错那么会自动的走then.reject ,
如果在then中没有reject回调,会在catch中进行错误捕获, catch方法也会捕获在then方法中发生任何错误。
错误处理?
增强用户体验
因为碰到异常后你的代码将不会往下执行
没有异常捕获的代码处于一种不可控的状态。
var msg = "";
try {
abc();
} catch (err) {
console.log(err)
console.log(err.message);
}
// 后面可以执行
console.log('执行了!')
finally(()=>{}) 无论promise执行成功或者失败,也无论catch方法是否执行, 最终finally都会执行。
finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
let flag = !true
new Promise((resolve, reject) => {
if (flag) {
resolve('成功')
} else {
reject('失败')
}
}).then( res => {
console.log(res)
} ).catch(err => {
console.log(err)
}).finally(console.log('关掉服务'))
不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。finally方法的回调函数不接受任何参数,所以不知道前面的 Promise 状态到底是fulfilled还是rejected。
finally方法里面的操作,与状态无关,不依赖于 Promise 的执行结果。
6.promise 创建成功就会立即执行(new Promise(同步的))
好处:
promise是一个对象,对象和函数的区别就是对象可以保存状态,函数不可以(闭包除外)
具有函数return的能力,不需要层层传递callback,进行回调获取数据。
new Promise(
function (resolve, reject) {
resolve('成功') // 数据处理完成
// reject('失败') // 数据处理出错
}
).then(
(res) => {console.log(res)}, // 成功
(err) => {console.log(err)} // 失败
)
7.Promise.all() 批量执行应用
图片加载
Promise.all() 方法接收一个promise的iterable类型,输入的所有promise的resolve回调的结果是一个数组。
let src1 = "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=153960715,2502274764&fm=26&gp=0.jpg"
let src2 = "https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=1474266791,210202337&fm=26&gp=0.jpg"
let src3 = "https://img2.baidu.com/it/u=142535408,4047253383&fm=26&fmt=auto&gp=0.jpg"
let imglist = document.getElementById("imglist")
console.dir(imglist);
function loadimg(src) {
return new Promise((resolve, reject) => {
let img = document.createElement("img")
img.setAttribute("src", src)
img.onload = function () {
console.log("加载");
resolve(img)
}
img.error = function () {
reject("失败")
}
})
}
let allimg = Promise.all([loadimg(src1), loadimg(src2), loadimg(src3)])
allimg.then(resolve => {
console.log(resolve);
resolve.forEach((i) => {
imglist.appendChild(i)
})
}).catch((error) => {
console.log("失败");
})
接受的参数是一个数组, 数组中的每个值是promise 实例对象, all()的状态是由参数的状态的决定 ; 所有的promise对象都成功则成功,有一个失败则失败
按照promise的添加顺序返回最终的结果。
8.Promise.race()的应用
图片加载
Promise.race([])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
function times() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve("超过二秒")
}, 2000)
})
}
let imgtimes = Promise.race([loadimg(src1), times()])
imgtimes.then(resolve => {
if (typeof resolve === "超过二秒") {
imglist.innerHTML("超时")
} else {
console.log(resolve);
imglist.appendChild(resolve)
}
}).catch(error => {
alert('失败');
})