ES6 promise 多请求一起执行


promise是什么

日常开发中,异步操作几乎每天都能见到。传统的意不解决方案是通过回调函数,随着程序逻辑越来越复杂,回调函数的方式变得越来越繁琐,很容易出现回调地狱,于是一种更合理更强大的代替方案出现–Promise

promise是异步编程的一种解决方案,指定回调函数的方式更加灵活。
支持链式调用,可以解决回调地狱问题


定义:

Promise 对象用于表示一个异步操作的最终完成 (或失败), 及其结果值.

语法:

new Promise( function(resolve, reject) {...} /* executor */  )

状态

  • pending: 初始状态,既不是成功,也不是失败状态。
  • fulfilled: 意味着操作成功完成。
  • rejected: 意味着操作失败。

一旦状态改变,就不会再变,任何时候都可以得到这个结果。

方法

  • then()
    当实例发生改变时的回调函数,返回的是一个新的promise实例,这也是promise能链式书写的原因
	const p = new Promise((resolve,rejected)=>{
			resolve('成功的数据')  //成功的方法,改变promise状态为成功
			rejected('失败的数据') //失败的方法,改变promise状态为失败
		})
		p.then(value=>{  //成功状态的调用方法
			console.log(value)
		},reason=>{      //失败状态的调用方法
			console.log(reason)
		})
  • catch()
    错误处理,用于指定发生错误的回调函数,常用catch()方法替代then()里面的第二个参数
		const p = new Promise((resolve,rejected)=>{
			resolve('成功的数据')  //成功的方法,改变promise状态为成功
			rejected('失败的数据') //失败的方法,改变promise状态为失败
		})
		p.then(value=>{  //成功状态的调用方法
			console.log(value)
		}).catch(value=>{   //错误处理用来替代then方法的第二个参数
			console.log(value)
		})
  • finally()
    用来指定不管promise对象状态最后如何都会执行的操作
		const p = new Promise((resolve,rejected)=>{
			rejected('失败的数据') //失败的方法,改变promise状态为失败
		})
		p.then(value=>{  //成功状态的调用方法
			console.log(value)
		}).catch(value=>{   //
			console.log(value)
		}).finally(()=>{
			console.log('finally操作')
		})
  • all()
    将多个promise实例包装成一个新的promise实例,所有promise实例执行成功,则成功
function p1(){
			return new Promise((resolve,rejected)=>{
				setTimeout(()=>{
					resolve('p1')
				},1000)
			})
		}
		function p2(){
			return new Promise((resolve,rejected)=>{
				setTimeout(()=>{
					resolve('p2')
				},2000)
			})
		}
		function p3(){
			return new Promise((resolve,rejected)=>{
				setTimeout(()=>{
					resolve('p3')
				},3000)
			})
		}
		
		const pAll = Promise.all([p1(),p2(),p3()])
		pAll.then(value=>{
			console.log(value)
		}).catch(value=>{
			console.log(value)
		}).finally(()=>{
			console.log(pAll)
		})

pAll 的状态由p1,p2,p3决定,只有当三个都为成功时,pAll状态才为成功

function p1(){
			return new Promise((resolve,rejected)=>{
				setTimeout(()=>{
					resolve('p1')
				},1000)
			})
		}
		function p2(){
			return new Promise((resolve,rejected)=>{
				setTimeout(()=>{
					rejected('p2')
				},2000)
			})
		}
		function p3(){
			return new Promise((resolve,rejected)=>{
				setTimeout(()=>{
					rejected('p3')
				},3000)
			})
		}
		
		const pAll = Promise.all([p1(),p2(),p3()])
		pAll.then(value=>{
			console.log(value)
		}).catch(value=>{
			console.log(value)
		}).finally(()=>{
			console.log(pAll)
		})

如果其中有一个为失败,pAll状态为失败,并且返回第一个失败实例的值为pAll 的值

function p1(){
			return new Promise((resolve,rejected)=>{
				setTimeout(()=>{
					resolve('p1')
				},1000)
			})
		}
		function p2(){
			return new Promise((resolve,rejected)=>{
				setTimeout(()=>{
					rejected('p2')
				},2000)
			}).catch(value =>{
				console.log('p2异常处理')
			})
		}
		function p3(){
			return new Promise((resolve,rejected)=>{
				setTimeout(()=>{
					resolve('p3')
				},3000)
			})
		}
		
		const pAll = Promise.all([p1(),p2(),p3()])
		pAll.then(value=>{
			console.log(value)
		}).catch(value=>{
			console.log(value)
		}).finally(()=>{
			console.log(pAll)
		})

如果作为参数的实例自己定义了catch方法,那么他出现失败结果不会影响pAll状态,但其值为undefined
[‘p1’, undefined, ‘p3’]

function p2(){
			return new Promise((resolve,rejected)=>{
				setTimeout(()=>{
					rejected('p2失败数据')
				},2000)
			}).catch(value =>{
				return value
			})
		}

则可以获取到p2 失败数据 [‘p1’, ‘p2失败数据’, ‘p3’]

  • race()
    将多个promise实例包装成一个新的promise实例
function p1(){
			return new Promise((resolve,rejected)=>{
				setTimeout(()=>{
					resolve('p1')
				},1000)
			})
		}
		function p2(){
			return new Promise((resolve,rejected)=>{
				setTimeout(()=>{
					resolve('p2')
				},2000)
			})
		}
		function p3(){
			return new Promise((resolve,rejected)=>{
				setTimeout(()=>{
					resolve('p3')
				},3000)
			})
		}
		
		const pRace = Promise.race([p1(),p2(),p3()])
		pRace.then(value=>{
			console.log(value)
		}).catch(value=>{
			console.log(value)
		}).finally(()=>{
			console.log(pRace)
		})

pRace 区别与 pAll 只要有一个实例先改变状态,就会把这个实例的返回值传给pRace的回调函数

一个有意思的小练习:发送请求,请求全部成功返回成功,不成功继续把没成功的请求继续发送,执行几次后还是失败就返回请求失败。

//发送请求
function p(num) {

        return new Promise((resolve, rejected) => {
            setTimeout(() => {

                if (num > 2) {
                    resolve('成功')
                } else {
                    rejected('失败')
                }
            }, 1000)
        }).then(value => {
            return false
        }).catch(value => {
            return true
        })
    }
	//参数
    let params = [1, 2, 3, 5]
    //存储返回值
    let arr = []
    //循环参数 发送请求
    for (let item of params) {
        arr.push(p(item))
    }
    
    send(arr, 0, params)
	//判断请求是否成功
    function send(promiseArr, stop, params) {
        if (stop >= 4) {
            alert('失败')
            return false
        }
        stop++
        console.log('stop: ' + stop)
        const pAll = Promise.all(promiseArr)
        pAll.then(value => {
            console.log(value)
            let valuearr = []
            value.forEach((item, index) => {
            	//判断是否有失败的
                if (item) { 
                    valuearr.push(
                        p(params[index])
                    )
                }
            })
            //判断还有没有失败的
            if (valuearr.length) {
                send(valuearr, stop, params)
            }else{
				alert('成功')
			}
        })
    }
  • allSettled()
    将多个promise实例包装成一个新的promise实例,所有promise实例执行完成后,则成功(不论里面promise是否成功)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值