es6 Promise

Promise的设计初衷

我们日常开发中,经常需要用到ajax请求数据,拿到数据后,再进行一些处理。
可有一次,你需要用ajax进行多次请求,而且,每次请求都依赖上一次请求返回的数据来作为参数,然后继续发出请求

——>然后你把代码写的稀碎:

	$.ajax({
		success:function(res1){
			$.ajax({
				success:function(res2){
					$.ajax({
						success:function(res3){
							......
						}
					})
				}
			})
		}
	})

这里假设每一次请求都需要上一次请求的返回结果

就这样—回调地狱就出现了。

很明显,这样缺陷很多:

  • 代码量大,可读性差,调试也不方便
  • 请求相互依赖的必须等待上一个请求完成后才可以执行,性能差,耗时

所以,Promise的出现为了使我们更合理更规范的进行异步操作处理。

Promise含义

Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

Promise状态
  • pending : 刚刚创建一个Promise实例的时候,表示初始状态
  • fulfilled : resolve方法调用的时候,表示操作成功
  • rejected : reject方法调用的时候,表示操作失败

状态只能从 初始化 -> 成功 或者 初始化 -> 失败,不能逆向转换,也不能在成功fulfilled 和失败rejected之间转换。

Promise特点
  • 对象的状态不受外界影响。Promise对象代表一个异步操作。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。
  • 一旦状态改变,就不会再变,任何时候都可以得到这个结果。

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。此外,Promise对象提供统一的接口,使得控制异步操作更加容易。

但是有好就会有不好

Promise缺点
  • 无法取消Promise,一旦新建它就会立即执行,无法中途取消。
  • 如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
  • 当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

Promise基本用法

Promise对象是全局对象,你也可以理解为一个类,创建Promise实例的时候,要有那个new关键字。参数是一个匿名函数,其中有两个参数:resolvereject,两个函数均为方法。
resolve方法用于处理异步操作成功后业务;
reject方法用于操作异步操作失败后的业务。

	let promise = new Promise(function(resolve,reject){
		//....
		if('异步操作成功'){
			resolve(res);
		}else{
			reject(err);
		}
	})

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去。

reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。


then()

then() : 用于绑定处理操作后的处理程序。

	promise.then(function(res){
		//操作成功的处理程序
	},function(err){
		//操作失败的处理程序
	})

then方法
第一个参数是resolved状态的回调函数,用于处理成功后的业务,
第二个参数是rejected状态的回调函数,用于处理操作异常后的业务。

catch()

catch() : 用于处理操作异常的业务

	promise.catch(function(err){
		//操作失败的处理程序
	})

catch方法只接受一个参数用于处理操作异常后的业务

所以日常开发中都两者结合使用。

	promise.then(res => {
		//操作成功的处理程序
	}).catch(err => {
		//操作失败的处理程序
	})
finally()

finally() :用于指定不管 Promise 对象最后状态如何,都会执行的操作

	promise
	.then(res => { .... })
	.catch(err => { ... })
	.finally(() => { ... })

finally方法的回调函数不接受任何参数,这意味着没有办法知道,前面的 Promise 状态到底是fulfilled还是rejected。这表明,finally方法里面的操作,应该是与状态无关的,不依赖于 Promise 的执行结果。

由于then和catch方法调用后,都返回Promise对象,所以可以链式调用


Promise.all()

Promise.all() :接受一个数组作为参数,数组的元素是Promise实例对象,当参数的实例对象的状态都为fulfilled时,Promise.all()才会有返回。

	//创建实例promise1
	let promise1 = new Promise(resolve => {
		setTimeout(() => {
			resolve('实例1操作成功')
		},5000);
	});

	//创建实例promise2
	let promise2 = new Promise(resolve => {
		setTimeout(() => {
			resolve('实例2操作成功')
		},1000);
	});

	Promise.all([promise1,promise2]).then(res => {
		console.log(res);// ["实例1操作成功", "实例2操作成功"]
	})

我们创建了两个Promise实例分别是promise1和promise2,两个setTimeout分别是5秒和1秒,当我们调用Promise.all()方法时,会延迟5秒控制台才会输出结果。
因为1秒以后,实例promise2进入了成功fulfilled状态;此时,Promise.all()还不会有所行动,因为实例promise1还没有进入fulfilled状态;等到了5秒后才进入成功状态;Promise.all()才会进入then方法,然后在控制台输出结果。

Promise.all()适用场景:执行一个操作,这个操作需要得到需要多个接口请求返回的数据来支持,但是这些接口请求之前互不依赖,不需要层层嵌套。这种场景就是适用Promise.all(),因为它会等到所有接口都请求成功了才会进行操作


Promise.race()

Promise.race() :它的参数要求和Promise.all()方法一样,不同的是,它参数中的Promise实例,只要有一个状态发生变化(不管是成功fulfilled还是失败rejected),它都会返回结果

	//初始化实例promise1
	let promise1 = new Promise(resolve => {
		setTimeout(() => {
			resolve('实例1操作成功')
		},5000)
	})

	//初始化实例promise2
	let promise2 = new Promise((resolve,reject) => {
		setTimeout(() => {
			reject('实例2操作失败')
		},1000)
	})

	Promise.race([promise2,promise1]).then(res => {
		console.log(res);
	}).catch(err => {
		console.log(err); // 实例2操作失败
	})

同样两个Promise实例,promise1不变,promise2调用操作失败函数reject
由于promise2中的1秒之后就执行reject方法,早于promise1的5秒,所以会输出:实例2操作失败

Promise.allSettled()

Promise.allSettled()方法接受一组Promise实例作为参数,包装成一个新的 Promise 实例。只有等到所有这些参数实例都返回结果,不管是fulfilled还是rejected,包装实例才会结束。

该方法返回的新的 Promise 实例,一旦结束,状态总是fulfilled,不会变成rejected。状态变成fulfilled后,Promise 的监听函数接收到的参数是一个数组,每个成员对应一个传入Promise.allSettled()的 Promise 实例。

Promise.any()

Promise.any()方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例。只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。

Promise.any()跟Promise.race()方法很像,只有一点不同,就是不会因为某个 Promise 变成rejected状态而结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值