文章目录
Promise
⭐ promise是什么?
Promise 对象是一个代理对象,通俗点讲可以把它理解为一个容器。它的参数是个回调函数,该回调接收一个resolve
和reject
函数,异步任务成功的结果绑定至resolve函数,失败的结果绑定至reject函数。
Promise状态
一个 Promise 对象具备三种状态
- pending: Promise新创建时的初始状态,还未执行 reslove 和 reject 方法
const pending_promise = new Promise((resolve, reject) => {
})
console.log(pending_promise)
- resolved/fulfilled: Promise对象在回调函数中调用了resolve方法后的状态
const resolve_promise = new Promise((resolve, reject) => {
resolve('resolve_promise')
})
console.log(resolve_promise)
- rejected: Promise对象在回调函数中调用了reject 方法后的状态
const reject_promise = new Promise((resolve, reject) => {
reject('reject_promise')
})
console.log(reject_promise)
Promise状态转换是不可逆的
,一旦从pending 状态转换至resolved/rejected,就不能再回到pending状态。
Promise使用——then、catch
Promise就是一个容器,将异步任务包裹在这个容器里即可,异步任务成功和失败的结果分别赋给给 resolve 函数和 reject函数
。
- promise读取图像
function loadImg(url) {
return new Promise((resolve, reject) => {
const img = document.createElement('img')
img.onload = () => {
resolve(img)
}
img.onerror = () => {
const err = new Error(`图片加载失败${url}`)
reject(err)
}
img.src = url
})
}
// 正确的图片地址
const url1 = 'https://profile.csdnimg.cn/4/8/2/3_qq_37987033'
// 错误的图片地址
const url2 = 'https://profile.csdnimgxx.cn/4/8/2/3_qq_37987033-error'
- then、catch方法捕获
使用 promise 的 then 方法能够获取状态为 resolved 时的对象,并进行后续处理。
then方法接收的是一个函数,该函数参数为promise执行 resolve 时带过来的值,如果传入的是其它的东西,then方法不会触发。
loadImg(url1).then(img => {
console.log(img)
})
使用 promise 的 catch 方法能够获取状态为 rejected 时的错误并抛出
loadImg(url2).catch((err) => {
console.error(err)
})
- 链式调用
promise在使用时允许链式调用
- 当前一个 promise 的状态为 resolved 时,会跳过 catch 进入下一个
then
方法;当前一个promise的状态为 rejected 时,会跳过 then 进入下一个catch
方法- 在使用链式调用时,then 方法中需要
一个返回值
作为下个 then 的输入,该返回值会自动被包裹成为一个promise对象
,因为只有promise 才有 ············then、catch方法。- 无论是then方法还是catch方法,只要它们
执行正常
,返回值都会变成resolved
状态;若执行过程中出错
,就会变成rejected
状态
loadImg(url1).then((img1) => {
console.log(img1.width, 1)
return img1
}).then(img1 => {
console.log(img1.height, 2)
return loadImg(url2)
}).then(img2 => {
console.log(img2, 3)
return img2
}).catch(err => {
console.error(err)
})
Promise的异步时机
promise在 new 时就会执行同步方法, resolve包裹而成的 Promise 对象在执行
then
时才是异步的。
const promise = new Promise((resolve, reject) => {
console.log(1);
resolve('resolve1');
console.log(2);
resolve('resolve2') // 状态只能改变一次
console.log(3);
});
// 异步
promise.then((res) => {
console.log(4,res);
});
console.log(5);
Promise其它方法——all、race
- all
Promise.all 接收一个Promise对象数组
- 对象数组里所有的 promise 对象
都成功
的时候才会触发成功- 对象数组里只要
有一个
promise 失败就会立即触发该 promise 。
// 成功的promise
const promise1 = new Promise((resolve, reject) => {
resolve('promise1')
})
// 成功的promise
const promise2 = new Promise((resolve, reject) => {
resolve('promise2')
})
// 失败的promise
const promise3 = new Promise((resolve, reject) => {
reject('promise3')
})
// promise.all 全部成功
Promise.all([promise1, promise2]).then(res => {
console.log(res);
});
// promise.all promise3失败成功
Promise.all([promise1, promise2, promise3]).then(res => {
console.log(res);
}).catch(err=>{
console.error(err)
})
- race
Promise.race 接收一个Promise对象数组
- race方法返回
第一个
执行完毕的 promise 的结果,该结果可以被t hen 或者 catch捕获。
const promise1 = new Promise((resolve, reject) => {
setTimeout(resolve, 100, 'promise1');
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(resolve, 50, 'promise2');
})
const promise3 = new Promise((resolve, reject) => {
setTimeout(reject, 30, 'promise3');
})
Promise.race([promise1, promise2]).then(res => {
console.log(res);
}).catch(err => {
console.error(err)
});
Promise.race([promise1, promise2, promise3]).then(res => {
console.log(res);
}).catch(err => {
console.error(err)
});
先返回 promise3(rejected)是因为定时器执行较早。
async、await
async / await 和Promise的关系
- ⭐ await需要被一个async函数包裹,后面跟一个promise对象,它们的存在消灭了
异步回调
。- 执行 async 函数,返回的是
Promise
对象,如果不是,它会自动
把返回值包裹成一个promise对象- await 相当于 Promise 的
then
;await后面可以跟:1Promise
对象;2 普通值(会包裹成Promise.resolve(xx));3 async函数的执行结果try...catch
可以捕获异常,代替了Promise 的catch
async / await 本身是Promise的语法糖
,它让原本的链式调用变成了真正的同步写法
。除此之外,async / await 可以使用 try/catch
捕获异常,这是它的一大优势。
async / await 使用
- async/await 读取图像
function loadImg(url) {
return new Promise((resolve, reject) => {
const img = document.createElement('img')
img.onload = () => {
resolve(img)
}
img.onerror = () => {
const err = new Error(`图片加载失败${url}`)
reject(err)
}
img.src = url
})
}
// 正确的图片地址
const url1 = 'https://profile.csdnimg.cn/4/8/2/3_qq_37987033'
// 错误的图片地址
const url2 = 'https://profile.csdnimgxx.cn/4/8/2/3_qq_37987033-error'
async function readImg() {
try {
const img1 = await loadImg(url1)
console.log(img1.width, img1.height)
const img2 = await loadImg(url2)
console.log(img2.width, img2.height)
} catch (error) {
console.log(error)
}
}
readImg()
输出如下👇
总结
Promise
- Promise状态
- Promise使用——then、catch
- Promise的异步时机
- Promise其它方法——all、race
async、await
- async / await 和Promise的关系
- async / await 使用