目录
Promise
promise是什么
Promise初体验
Promise 的状态改变
Promise的实例方法
then方法
then的多次调用
then的返回值
catch方法
catch的多次调用
catch的返回值
catch与then第二个参数的区别
finally方法
Promise中的类方法/静态方法
Promise.reslove
Promise.reject
Promise.all
Promise.allSettled
Promise.race
Promise.any
async 与 await
Promise是处理异步问题的一种方式,之前都是用回调函数,如setTimeout( ( )=>{ } ,2000),
相对于传统的回调函数处理异步问题,Promise有以下几个好处:
解决了回调地狱的问题,以一种更线性的Promise链形式表达出来,更容易阅读和推断
回调函数难以处理错误:Promise链提供了一种让错误正确传播的途径
Promise 是一门新的技术(ES6 规范)
Promise 是 JS 中进行异步编程的新解决方案(备注:旧方案是单纯使用回调函数)
从语法上来说: Promise 是一个构造函数
从功能上来说: promise 对象用来封装一个异步操作并可以获取其成功/失败的结果值
Promise(承诺),给予调用者一个承诺,过一会返回数据给你,就可以创建一个promise对象
当我们new一个promise,此时我们需要传递一个回调函数,这个函数为立即执行的,称之为(executor)
这个回调函数,我们需要传入两个参数回调函数reslove,reject
当执行了reslove函数,会回调promise对象的.then函数
当执行了reject函数,会回调promise对象的.catche函数
抽奖样例(Promise实现):
pending 变为 resolved
pending 变为 rejected
【说明】:
只有这 2 种, 且一个 promise 对象只能改变一次
无论变为成功还是失败, 都会有一个结果数据
成功的结果数据一般称为 value, 失败的结果数据一般称为 reason,可以通过resolve和reject函数传递给then中方法。
Promise的函数参数是同步执行的,then方法是异步的!
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
reject('失败')
resolve('成功')
}, 3000);
})
promise.then(res => console.log(res)).catch(err => console.log(err))
resolve不同值的区别
resolve
传入一个普通的值或者对象,只能传递接受一个参数,那么这个值会作为then
回调的参数
const promise = new Promise((resolve, reject) => {
resolve({name: 'ice', age: 22})
})
promise.then(res => console.log(res))
// {name: 'ice', age: 22}
如果resolve
中传入的是另外一个Promise
,那么这个新Promise
会决定原Promise
的状态
const promise = new Promise((resolve, reject) => {
resolve(new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ice')
}, 3000);
}))
})
promise.then(res => console.log(res))
//3s后 ice
resolve
中传入的是一个对象,并且这个对象有实现then
方法,那么会执行该then
方法,then
方法会传入resolve
,reject
函数。此时的promise
状态取决于你调用了resolve
,还是reject
函数。这种模式也称之为: thenableconst promise = new Promise((resolve, reject) => {
resolve({
then(res, rej) {
res('hi ice')
}
})
})
promise.then(res => console.log(res))
// hi ice
then
方法可以接受参数,一个参数为成功的回调,另一个参数为失败的回调
const promise = new Promise((resolve, reject) => {
resolve('request success')
// reject('request error')
})
promise.then(res => console.log(res), rej => console.log(rej))
//request success
then的多次调用则会执行多次
const promise = new Promise((resolve, reject) => {
resolve('hi ice')
})
promise.then(res => console.log(res))
promise.then(res => console.log(res))
promise.then(res => console.log(res))
//hi ice
//hi ice
//hi ice
then
方法是有返回值的,它的返回值是promise
。
但是是promise那它的状态如何决定呢?接下来让我们一探究竟。
则相当于主动调用Promise.resolve,并且把返回值作为实参传递到then方法中
如果没有返回值,则相当于返回undefined
那么取决于返回的这个Promise对象的状态
同.then方法,也会执行多次
catch方法也是有返回值的,返回的也是一个Promise对象,而且这个Promise对象的状态确定方法与then方法完全一致。
catch是用来处理异常的,那么catch与.then方法的第二个回调函数有什么区别呢?
主要区别就是:如果在then的第一个函数里抛出了异常,后面的catch能捕获到,而then的第二个函数捕获不到。
finally
方法Promise.resolve('ice')
//等价于
new Promise((resolve, reject) => resolve('ice'))
有的时候,你已经预知了状态的结果为fulfilled,则可以用这种简写方式
类似地,可以得到一个状态为rejected的Promise对象
resolve
状态的时候才会调用.then
方法。.catch
方法let p1 = new Promise((resolve, reject) => {
resolve('成功了')
})
let p2 = new Promise((resolve, reject) => {
resolve('success')
})
let p3 = Promise.reject('失败')
Promise.all([p1, p2]).then((result) => {
console.log(result) //['成功了', 'success']
}).catch((error) => {
console.log(error)
})
Promise.all([p1,p3,p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 失败了,打出 '失败'
})
上面的Promise.all
有一个缺陷,就是当遇到一个rejected的状态,那么对于后面是resolve
或者reject
的结果我们是拿不到的,因此ES11 新增语法Promise.allSettled
,无论状态是fulfilled/rejected都会把参数返回给我们
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('hi ice')
}, 1000);
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hi panda')
}, 2000);
})
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('hi grizzly')
}, 3000);
})
Promise.allSettled([promise1, promise2, promise3]).then(res => console.log(res))
/* [
{ status: 'rejected', reason: 'hi ice' },
{ status: 'fulfilled', value: 'hi panda' },
{ status: 'rejected', reason: 'hi grizzly' }
] */
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('hi error')
}, 1000);
})
const promise2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hi panda')
}, 2000);
})
Promise.race([promise1, promise2])
.then(res => console.log(res))
.catch(e => console.log(e))
//hi error
AggregateError
异步函数(async function)中可以使用await
关键字,普通函数不行
通常await关键字后面都是跟一个Promise
resolve或者reject
这个promise状态变为fulfilled才会执行await
后续的代码,所以await
后面的代码,相当于包括在.then
方法的回调中,如果状态变为rejected,你则需要在函数内部try catch
,或者进行链式调用进行.catch
操作