JavaScript异步编程---Promise详解

Promise概述

在异步编程中直接使用传统回调的方式去完成复杂的异步流程,那就无法避免大量的回调函数嵌套,这就会导致回调地狱问题。举个例子:
在这里插入图片描述
为了避免这个问题,CommonJS社区提出了Promise的规范,在ES2015中被纳入规范。
Promise实际上就是一个对象用来表示异步任务在执行过后是成功还是失败。一开始这个承诺是待定的状态,在执行过后有两个结果,成功或者失败。不管是成功还是失败,都会有对应得反应方法。
在这里插入图片描述
在结果产生后对应得方法都会自动执行,出自之外还有一个特性,就是这个结果一旦产生那就无法更改,即便在后面重新执行成功,但对于一开始的Promise对象始终是失败的。

Promise基本用法

在代码层面Promise就是ES2015所提供的全局类型。
该类型的构造函数中需要接收一个函数对象作为参数。该函数会在构造Promise的过程中被同步执行,在函数内部可以接收到两个参数,分别是resolve、reject,这两个参数都是一个函数 ,resolve的作用就是将Promise的状态改为成功,一般我们将异步任务的操作结果通过这个函数的参数传递出去。
在reject方法中,传递的一般都是一个错误对象。
在这里插入图片描述
需要注意的是,即便Promise中就算没有任何异步操作,then方法当中指定的回调函数仍然会进入回调队列中进行排队,也就是说必须要等待同步代码全部执行完了then中的方法才会执行。

Promise使用案例

在这里插入图片描述

Promise常见误区

Promise从表象上来看就是使用回调函数的方式去定义异步任务结束后所需要执行的任务,只不过这里的回调函数是通过then方法传进去的,并且将回调分成了两种。
但是在需要连续执行多个异步函数的时候,有的人可能就会说了,还是会有嵌套回调的问题,具体例子如下图:
在这里插入图片描述
其实,这种嵌套使用的方式是我们使用Promise常见的误区,正确的做法是借助于Promise.then方法的链式调用的特点,尽可能保证异步任务的扁平化。

Promise链式调用

链式调用是promise和传统回调函数的区别所在,通过链式调用就能最大程度地避免回调的嵌套。
通常在then方法中,失败的回调函数可以省略。且每一个then方法都会返回一个全新的Promise对象。

  1. 每一个then方法都是在为上一个then返回的Promise对象添加状态明确过后的回调。
  2. 前面then方法中回调函数的返回值会作为后面then方法的参数。
  3. 如果回调中返回的是Promise,那后面的then方法的回调会等待它的结束
    在这里插入图片描述

Promise异常处理

在这里插入图片描述
用catch方法和 .then方法都能捕获到在执行过程中遇到的异常。
但是这两种方式其实有很大的差异,因为每个then方法都会返回一个全新的promise对象,这也就是说我们的 .catch方法其实是在给前面 then方法返回的全新的promise对象去指定失败的回调,不是给第一个promise指定失败的回调。只是由于是在同一根promise链条,所以,异常会一直往后传递。
具体在表现上的差异是,假如我们在then方法中返回了一个新的promise,并且中间出现了异常,使用then的第二个回调函数参数,是捕获不到异常的,因为这两个回调函数是给第一个promise的。而catch则可以。
所以对于链式调用,建议使用catch来分开成功回调和失败回调。

Promise静态方法

Promise.resolve( )
这个方法的作用就是快速把一个值转换为一个promise对象,假如传入一个‘test’的字符串,那就会返回一个状态为成功的promise对象,这个字符串就会作为成功时回调函数传入的参数
假如接收到的是一个promise对象,那么这个对象就会被原样返回。
相对于Promise.resolve( )还有一个Promise.rejected( )方法
会返回一个一定是失败的promise对象。传入的参数会作为promise失败的原因

Promise并行执行

上文中提到的所有操作都是通过Promise去串联执行多个异步任务,也就是一个任务结束之后再去开启下个任务。
如果我们需要我们同时并行执行多个异步任务,Promise也能提供相应的支持。最常见的案例就是在一个页面需要请求多个接口,如果这些请求之间没有互相依赖的关系,最好的做法就是同时去请求它们。
这也很容易实现,只需要单独调用ajax请求即可。但是与之而来有一个问题,无法得知他们全部执行完的时机,以往的做法就是设置一个计数器,每有一个异步请求执行完,计数器++,直到计数器的数量和任务数量相等。该种方法较为麻烦,还需要考虑可能会出现异常时的情况。
此时就需要使用Promise的all方法。
该方法可以将多个Promise合并为一个Promise统一去管理。
在这里插入图片描述
Promise也有一个race()方法,该方法的作用也是把多个promise对象组合为一个全新的promise对象但是与all( )有所不同的是,all方法需要等待所有任务结束,而rece方法只会等待第一个任务结束。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值