ES6之Promise

参考链接

ES5中实现异步的常见方式不外乎以下几种:

  1. 回调函数
  2. 事件驱动
  3. 自定义事件(根本上原理同事件驱动相同)

而ES6中的Promise的出现就使得异步变得非常简单。promise中的异步是这样的:

  • 每当我需要执行一次异步操作的时候,我都需要new一个promise对象
  • 每一个异步操作的Promise对象都需要设定一个成功执行的条件和成功的回调、一个失败的条件和失败的回调
  • Promise对象可通过执行then()方法获得成功的回调信息
  • Promise对象可通过执行catch()方法捕获失败的回调信息(当不执行catch方法时,若异步操作失败会报错)

一次常规异步操作的流程大致是这样的:

new Promise((resolve, reject)=>{
        if(...){             // 设定异步操作成功的条件
            resolve()        // 设定异步操作成功 并返回 成功的回调信息
        } 
        else{               // 设定异步操作失败的条件
            reject()        // 设定异步操作失败 并返回 失败的回调
        }
    })
    .then((res)=>{         //执行异步操作,并且执行成功
        .....             // 异步操作成功后的后续操作
        ...
        ..               
    })
    .catch((err)=>{    // 执行一步操作,异步操作失败
        .....          // 操作失败的后续操作
        ...
        ..
    })

下面首先通过一个简单的例子来基本套用一下异步操作的流程
实际项目中经常会有这样的需求,很多功能都是需要在登录后才能去实现的,比如说我想要查看用户的个人信息,那么这个用户就必须先要登录,那么分解步骤后:

  • 第一步: 执行登录并且登录成功
  • 第二步: 登录成功,开始获取用户信息
  • 第三步: 获取用户信息成功,返回用户信息或成功的回调信息

以上三步操作,需要两次异步操作,就需要两个异步的Promise对象

首先是准备工作:

// 两个状态用以分别判断两次异步操作是否成功
    let status1 = 1;
    let status2 = 1;
    // 设定登录的异步操作
    let doLogin = (resolve, reject) =>{
        setTimeout(()=>{
            if(status1 ==1){
                resolve({status:1,msg: `异步执行 login ok`})
            }else{
                reject({status:0,msg: `异步执行 login failed`});
            }
        },2000)
    }
    // 设定获取用户信息的异步操作
    let getUserInfo = (resolve, reject)=>{
        setTimeout(()=>{
            if(status2==1){
                resolve({status:1,msg: `异步执行 get user info ok`});
            }else{
                reject({status:0,msg: `异步执行 get user info failed`});
            }
        },1000)
    }

紧接着开始执行异步操作:

new Promise(doLogin)
    .then((res)=>{
            console.log(res.msg);
            return new Promise(getUserInfo)     // 若下一步要执行异步操作则必须返回一个promise对象用以链式操作
    })
    .then((res)=>{
        console.log(res.msg)
    })
    .catch((err)=>{
        console.log(err.msg)
    })

整体代码及运行结果:

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
<script type="text/javascript">
	// 用两个状态来模拟两次异步操作是否成功
	let status1 = 1;
	let status2 = 2;
	// 模拟登录的异步操作
	let doLogin = (resolve, reject)=>{
		setTimeout(() => {
			if (status1 === 1) {
				resolve({status: 1, msg: '异步login执行成功'})
			}else {
				reject({status: 0, msg: '异步login失败'})
			}
		}, 3000)
	}
	// 模拟获取用户信息的异步操作
	let getUserInfo = (resolve, reject) => {
		setTimeout(() => {
			if(status2 === 2) {
				resolve({status: 1, msg: '异步获取用户信息成功!'})
			}else {
				reject({status: 0, msg: '异步获取用户失败'})
			}

		}, 1000)
	}

	// 创建Promise对象
	//使用then来捕捉resolve状态,使用catch来捕捉reject状态
	new Promise(doLogin)
	.then((res) => {
		// if (res.status === 1) {
			console.log(res.status, res.msg)
			return new Promise(getUserInfo)
		// }
		// else {
		// 	console.log('aaaaaaaa')
		// 	console.log(res.status, res.msg)
		// }
	})
	.then((res) => {
		// if (res.status === 1) {
			console.log(res.status, res.msg)
		// }
		// else {
		// 	console.log(res.status, res.msg)
		// }
	})
	.catch((err) => {
		console.error(err.status, err.msg)
	})
	//这里需要注意的是,在链式调用的最后一定要加上一个catch来捕捉链条中可能出现的错误!
</script>
</body>
</html>

在这里插入图片描述
上面的例子搞清楚之后差不多也就理解了promise的基本用法。

Promise.all() 多异步操作,所有异步执行需全部成功
all() 方法需要传入的参数为对象数组,只有当数组中的所有异步对象都能够成功回调后,all() 方法返回的promise对象才能执行成功的回调。
*创建Promise对象:

// 创建Promise对象
		function createPro(flag, oSucc, oFail) {
			return new Promise((resolve, reject) => {
				if(flag) {
					resolve(oSucc)
				}
				else{
					reject(oFail)
				}
			})
		}

*当所有异步对象都执行成功时,all方法的then才会执行,返回一个所有对象成功回调数据的集合;否则执行catch,返回第一个失败的异步回调信息。

let p1 = createPro(true,{status:1,msg:"异步成功1"},{status:0,msg:"异步失败1"})
		let p2 = createPro(true,{status:1,msg:"异步成功2"},{status:0,msg:"异步失败2"})
		let p3 = createPro(true,{status:1,msg:"异步成功3"},{status:0,msg:"异步失败3"})
		Promise.all([p1, p2, p3])
		.then(res => {
			console.log(res)
		})
		.catch(err => {
			console.log(err)
		})

完整代码实例及结果:

<!DOCTYPE html>
<html>
<head>
	<title></title>
</head>
<body>
	<script type="text/javascript">
		// 创建Promise对象
		function createPro(flag, oSucc, oFail) {
			return new Promise((resolve, reject) => {
				if(flag) {
					resolve(oSucc)
				}
				else{
					reject(oFail)
				}
			})
		}
		//当所有异步对象都执行成功时,all方法的then才会执行,返回一个所有对象成功回调数据的集合;否则执行catch,返回第一个失败的异步回调信息
		let p1 = createPro(true,{status:1,msg:"异步成功1"},{status:0,msg:"异步失败1"})
		let p2 = createPro(true,{status:1,msg:"异步成功2"},{status:0,msg:"异步失败2"})
		let p3 = createPro(true,{status:1,msg:"异步成功3"},{status:0,msg:"异步失败3"})
		Promise.all([p1, p2, p3])
		.then(res => {
			console.log(res)
		})
		.catch(err => {
			console.log(err)
		})
	</script>
</body>
</html>

在这里插入图片描述

*当出现失败的异步操作时,则返回第一个失败的异步回调信息

let p1 = createPro(true,{status:1,msg:"异步成功1"},{status:0,msg:"异步失败1"})
		let p2 = createPro(false,{status:1,msg:"异步成功2"},{status:0,msg:"异步失败2"})
		let p3 = createPro(true,{status:1,msg:"异步成功3"},{status:0,msg:"异步失败3"})
		Promise.all([p1, p2, p3])
		.then(res => {
			console.log(res)
		})
		.catch(err => {
			console.log(err)
		})

在这里插入图片描述

Promise.race() 多异步操作,顾名思义,返回的为第一个执行完成的回调信息,无论是成功还是失败。
看的是执行的速度,谁快返回谁:

function creatPro (flag,oSucc,oFail,timeout) {
        let pro = new Promise((resolve, reject)=>{
            setTimeout(()=>{
                if(flag){
                    resolve(oSucc)
                }else{
                    reject(oFail)
                }
            },timeout)
        })
        return pro
    }

    let p1 = creatPro(true,{status:1,msg:"异步成功1"},{status:0,msg:"异步失败1"},5000);
    let p2 = creatPro(false,{status:1,msg:"异步成功2"},{status:0,msg:"异步失败2"},1000);
    let p3 = creatPro(true,{status:1,msg:"异步成功3"},{status:0,msg:"异步失败3"},500);

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

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

. . . . .

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值