Promise 浅析

一、Promise 出现的原因

为了解决异步嵌套(回调地狱)的问题。

  • 场景:需要根据第一个请求的结果,再去执行第二个请求
请求1( (请求1的结果) => {
	请求2( (请求2的结果) => {
		// 处理结果...
	} )
} )

===> 如果存在更多层的嵌套:

请求1( (请求1的结果) => {
	请求2( (请求2的结果) => {
		请求3( (请求3的结果) => {
			请求4( (请求4的结果) => {
				请求5( (请求5的结果) => {
					// 处理结果...
				} )
			} )
		} )
	} )
} )
// 我们还需要对每一层的请求结果进行处理...

存在的问题:

  • 代码臃肿;
  • 可读性差;
  • 过渡耦合;
  • 维护成本高;
  • 只能在回调里处理有异常。

出现了问题,就会有人想办法解决问题。那么,能不能用一种友好的代码书写方式来解决异步嵌套的问题,形如:

const 请求1结果 = 请求1( );
const 请求2结果 = 请求2( 请求1结果 );
const 请求3结果 = 请求3( 请求2结果 );
const 请求4结果 = 请求4( 请求3结果 );
const 请求5结果 = 请求5( 请求4结果 );
最终处理( 请求5结果 );

于是Promise规范诞生了,并且有了很多实现来解决回调地狱的痛点。
Promise规范: Promise/A(升级版:Promise/A+),Promise/B,Promise/D …
ES6 中采用了 Promise/A+ 规范。


二、什么是Promise

Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。现已被 ES6 纳入进规范中。

书写:

new Promise(请求1)
    .then(请求2(请求结果1))
    .then(请求3(请求结果2))
    .then(请求4(请求结果3))
    .then(请求5(请求结果4))
    .catch(处理异常(异常信息))

不难看出,与前面回调式的写法相比,Promise的写法更直观,并且能够在外层捕获异常信息。

三、 使用方法

  1. Promise.prototype.then
	实例方法,为 Promise 注册回调函数,函数形式:fn(vlaue){},value 是上一个任务的返回结果,then 中的函数一定要 return 一个结果或者一个新的 Promise 对象,才可以让之后的then 回调接收。
  1. Promise.prototype.catch
	实例方法,捕获异常,函数形式:fn(err){}, err 是 catch 注册 之前的回调抛出的异常信息。
  1. Promise.prototype.finally
	实例方法,注意点:
	a. finally() 方法的回调函数不接受任何参数;
	b. 无论成功还是失败都会执行;
	c. finally() 方法总是会返回原来的值。
  1. Promise.resolve(value)
	类方法,该方法返回一个以 value 值解析后的 Promise 对象。
	a. 如果这个值是个 thenable(即带有 then 方法),返回的 Promise 对象会“跟随”这个 thenable 的对象,采用它的最终状态(指 resolved/rejected/pending/settled)
	b. 如果传入的 value 本身就是 Promise 对象,则该对象作为 Promise.resolve 方法的返回值返回。
	c. 其他情况以该值为成功状态返回一个 Promise 对象。
  1. Promise.reject
	类方法,且与 resolve 唯一的不同是,返回的 promise 对象的状态为 rejected。
  1. Promise.race
	类方法,多个 Promise 任务同时执行,返回最先执行结束的 Promise 任务的结果,不管这个 Promise 结果是成功还是失败。 。
  1. Promise.all
	类方法,多个 Promise 任务同时执行。如果全部成功执行,则以数组的方式返回所有 Promise 任务的执行结果。 如果有一个 Promise 任务 rejected,则只返回 rejected 任务的结果。

**使用总结**
  1. 首先初始化一个Promise对象,以下两种方式都会返回一个Promise对象;
	a. new Promise( (resolve, reject) => {  } )
	b. Promise.resolve( ( res ) => { } )
  1. 然后调用上一步返回的 promise 对象的 then 方法,注册回调函数;
  2. 最后注册 catch 异常处理函数,处理前面回调中可能抛出的异常。

四、Promise与事件循环

romise在初始化时,传入的函数是同步执行的,然后注册 then 回调。注册完之后,继续往下执行同步代码,在这之前,then 中回调不会执行。同步代码块执行完毕后,才会在事件循环中检测是否有可用的 promise 回调,如果有,那么执行,如果没有,继续下一个事件循环。


五、同步使用Promise

ES6 出现了 generator 以及 async/await 语法,使异步处理更加接近同步代码写法,可读性更好,同时异常捕获和同步代码的书写趋于一致。上面的列子可以写成这样:

const fn = async () => {
	try {
		const res1 = await 请求1();
		const res2 = await 请求2();
		const res3 = await 请求3();
		...
	} catch ( e ) {
		// 异常处理...
	}
}

六、Promise 详解

点击跳转

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值