Js之Promise使用总结

297 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第26天,点击查看活动详情

前言

Promise 是ES6新增的一个异步编程的一个对象,因为JS本身是单线程的,所以当碰到需要做异步操作的时候,我们就得考虑其他方案了,Promise就可以为我们解决这样的问题。

Promise状态

总共有三种状态

  • 待定(pending): 初始状态,既没有被兑现,也没有被拒绝;

当执行executor中的代码时,处于该状态;

  • 已成功(fulfilled): 意味着操作成功完成;

执行了resolve时,处于该状态,Promise已经被兑现;

  • 已拒绝(rejected): 意味着操作失败;

执行了reject时,处于该状态,Promise已经被拒绝;

Promise基础使用

let p = new Promise(function(resolve, reject){
		//做一些异步操作
		setTimeout(function(){
			console.log('执行完成Promise');
			resolve('要返回的数据可以任何数据例如接口返回数据');
		}, 2000);
	});
p.then(res=>{
    console.log('收到返回结果',res)
})

image.png

如上,若通过new关键字声明一个Promise对象,则需要传入一个函数,其参数分别为2个回调函数 resolve和reject。

如果resolve回调的不是一个Promise对象,那么这个promise对象就已经确定了状态,表示执行成功了,不可改变,最后可以通过then函数接收这个回调的值。

resolve方法

resolve是一个Promise类的方法,可以直接通过Promise.reslove('gogo')直接调用,等同于 new Promise((resolve)=>resolve(''gogo))

  1. 情况一:如果resolve传入一个普通的值或者对象,那么这个值会作为then回调的参数。

  2. 情况二:如果resolve中传入的是另外一个Promise,那么这个新Promise会决定原Promise的状态。

new Promise(function(resolve, reject){
        resolve(new Promise(function(resolve, reject){
            setTimeout(function(){
			    resolve('第二个promise回调');
		    }, 2000);
        }))
		
	}).then(res=>{
        console.log('res: ', res);
        
    })

image.png

  1. 情况三:如果resolve中传入的是一个对象,并且这个对象有实现then方法,那么会执行该then方法,并且根据then方法的结果来决定Promise的状态。
 new Promise(function(resolve, reject){
        resolve({
            then:function(resolve, reject){
                console.log('then方法回调' );

            }
        })
		
	}).then(res=>{
        console.log('res: ', res);
        
    })

image.png

then方法讲解

then方法是Promise对象原型上的一个方法,它接收2个参数,一个是成功状态的回调函数,一个是失败状态的回调函数,所以完整写法如下

let p = new Promise(function(resolve, reject){
		//做一些异步操作
		// setTimeout(function(){
		// 	console.log('执行完成Promise');
		// 	resolve('要返回的数据可以任何数据例如接口返回数据');
		// }, 2000);
        reject('发生了错误')
	});
p.then(res=>{
    console.log('收到返回结果',res)
},err=>{
    console.log('收到reject请求',err)
})

这里我们reject一个错误回调,可以看到打印结果如下

image.png

then方法可以被多次调用,依次都会执行。

then方法也可以有返回值,并且当then方法中的回调函数返回一个结果时,那么它处于fulfilled状态,并且会将结果作为resolve的参数;

  • 返回一个普通的值;

  • 返回一个Promise;

  • 返回一个thenable值;

当then方法抛出一个异常时,那么它处于reject状态;

catch方法

这个方法跟then方法类似,都属于Promise实例对象上的方法,同样也可以多次调用。从字面看不难理解它就是一个捕获错误的方法。

注意的是如果写了catch方法,那then方法里面就不用额外传第二个参数了。

p.then(res=>{
    console.log('收到返回结果',res)
}).catch(err=>{
    console.log('catch:收到reject请求',err)
    })

image.png

如果需要多次调用catch,那么在上一个catch需要抛出新的错误,throw new Error('新的错误')。

finally方法

这个方法表示无论Promise对象无论变成fulfilled还是rejected状态,最终都会被执行。


p.then(res=>{
    console.log('收到返回结果',res)
}).catch(err=>{
    console.log('catch:收到reject请求',err)
    }).finally(()=>{
         console.log('肯定会执行')
    })

all方法

这是一个类方法,是将多个Promise包裹在一起形成一个新的Promise。需要注意的是

  • 当所有的Promise状态变成fulfilled状态时,新的Promise状态为fulfilled,并且会将所有Promise的返回值组成一个数组;

  • 当有一个Promise状态为reject时,新的Promise状态为reject,并且会将第一个reject的返回值作为参数;

  const p1=new Promise(function(resolve,reject){
        resolve('我是p1')
       

    })
     const p2=new Promise(function(resolve,reject){
        resolve('我是p2')
       
        
    })
     const p3=new Promise(function(resolve,reject){
        resolve('我是p3')
        
    })

    Promise.all([p1,p2,p3]).then(res=>{
         console.log(res);
    })

image.png

allSettled方法

该方法的特点是

  • 该方法会在所有的Promise都有结果(settled),无论是fulfilled,还是rejected时,才会有最终的状态;

  • 并且这个Promise的结果一定是fulfilled的;

Promise.allSettled([p1,p2,p3]).then(res=>{
         console.log(res);
    })

image.png

race方法

这个方法用的应该比较少,它的意思是多个Promise,谁先有结果,就先用谁的。

  Promise.race([p1,p2,p3]).then(res=>{
         console.log(res);
    }).catch(err=>{
         console.log('race:',err);
    })

any方法

  • 如果有一个 Promise 的状态为成功(fulfilled),p 的状态为成功(resolved)。

  • 如果所有的Promise都是reject的,那么也会等到所有的Promise都变成rejected状态。

总结

Promise算是比较常用的一个js对象了,掌握Promise也是必不可少,也是面试经常问的,先掌握使用在然后深入原理。