Promise 的作用以及基本使用
关于 Promise 的概念, 对于从事前端行业的同学们来说,已经是一个老生常谈的问题了,也会经常被面试官问到,然后就是经常回答不到点上,那么我今天就来详细的总结一下它的具体作用与如何来使用 Promise。
什么是Promise
Promise对象作为 ES6出来的新特性,它可以理解为一次执行的异步操作,使用Promise对象之后可以使用一种链式调用的方式来组织代码;让代码更加的直观。也就是说,有了Promise对象,就可以将异步操作以同步的操作的流程表达出来,避免了层层嵌套的回调函数。
如何使用Promise呢
在使用之前我们需要先了解一下它的一些特点。
Promise 三种状态
- pending :进行中,表示 Promise 还在执行阶段,没有执行完成。
- fulfilled:成功状态,表示 Promise 成功执行完成。
- rejected:拒绝状态,表示 Promise 执行被拒绝,也就是失败。
Promise 的状态,只可能是其中一种状态,从进行中变为成功或失败状态之后,状态就固定了,不会再发生改变。
然后呢,它还具有一些基础功能,也就是 then
、catch
和 finally
基本概念
- then () :为 Promise 实例添加状态改变时的回调函数,
then
方法的第一个参数是resolved
状态的回调函数,第二个参数是rejected
状态的回调函数,它们都是可选的。 - catch () :用于指定发生错误时的回调函数
- finally () :不管 Promise 对象最后状态如何,都会执行的操作
接下来就让我们仔仔细细的看看代码是怎么写的
const p = new Promise((resolve,reject) => {
setTimeout(() => {
resolve('哇哈哈')
// reject('失败了')
}, 1000)
}).then(res => {
console.log(res) // 一秒后打印出哇哈哈
}).catch(error => {
console.log(error) // 此处会打印reject()里面的值
}).finally(() => {
console.log('finally') // 此处代表整个 Promise 对象最后状态如何,都会执行的操作。
})
链式调用then
- 每次你对 Promise 调用 then(..),它都会创建并返回一个新的 Promise,我们可以将其连接起来;
- 不管从 then(..) 调用的完成回调(第一个参数)返回的值是什么,它都会被自动设置为被链接 Promise(第一点中的)的完成。
代码如下:
// 定义一个add的数字
function add(num){
return new Promise((resolve,reject)=>{
resolve(num+1)
})
}
//利用add来
add(1).then(res=>{
console.log('展示1',res);
return add(res)
}).then(res=>{
console.log('展示2',res);
return add(res)
}).then(res=>{
console.log('展示3',res);
})
// 控制台按顺序打印
// 展示1 2
// 展示2 3
// 展示3 4
Promise的静态方法
Promise.all()
Promise.all(),提供了并行执行异步操作的能力,并且在所有异步操作完成之后,统一返回所有结果。具体使用如:
const promise1 = Promise.resolve(3)
const promise2 = 42
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('foo')
}, 100)
})
Promise.all([promise1, promise2, promise3]).then((values) => {
console.log(values) // 结果为:3 42 foo
})
all 接收到的是一个数组,数组长度取决于 Promise 的个数。
一些游戏类的素材比较多的应用,打开网页时,预先加载需要用到的各类资源,所有的都加载完后,再进行页面的初始化。
Promise.race()
race翻译成中文:赛跑。就是谁跑得最快,谁才能触碰到终点的胜利线。
Promise.race 用法与 all 一样,只是返回结果上不同,它返回的是执行最快的那个 Promise 的结果。
const promise1 = Promise.reject('失败')
const promise2 = new Promise((resolve,reject)=> {
setTimeout(() => {
resolve('成功2')
}, 200)
})
const promise3 = Promise.resolve('成功3')
Promise.race([promise1,promise2,promise3]).then(values => {
console.log(values)
}).catch(err => {
console.log(err,'err') // 结果为:失败
})
Promise.allSettled()
Promise.all()
方法会在任何一个输入的 Promise 被拒绝时立即拒绝。而Promise.allSettled()
方法返回的 Promise 会等待所有输入的 Promise 完成,不管其中是否有 Promise 被拒绝。如果你需要获取输入可迭代对象中每个 Promise 的最终结果,则应使用 allSettled()
方法。
const promise1 = Promise.reject(3)
const promise2 = 42
const promise3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('foo')
}, 100)
})
Promise.allSettled([promise3,promise2,promise1]).then(values => {
console.log(values)
/* 结果为:
values === [
{status: 'fulfilled', value: 'foo'}
{status: 'fulfilled', value: 42}
{status: 'rejected', reason: 3}
]
**/
})
Promise.any()
Promise.any()
跟 Promise.race()
方法很像,只有一点不同,就是 Promise.any()
不会因为某个 Promise 变成 rejected
状态而结束,必须等到所有参数 Promise 变成 rejected
状态才会结束。
- 只要有一个Promise实例请求成功,调用then回调函数
- 全部Promise实例请求失败,才会调用catch回调函数
const promise1 = Promise.reject('失败')
const promise2 = new Promise((resolve,reject)=> {
setTimeout(() => {
resolve('成功2')
}, 200)
})
const promise3 = Promise.resolve('成功3')
Promise.any([promise1,promise2,promise3]).then(values => {
console.log(values); // 结果为:成功3
}).catch(err => {
console.log(err,'err')
})
转载自:https://juejin.cn/post/7262287796038303801