彻底搞懂promise
我们知道在js中任务分为同步任务和异步任务 同步任务就是按照顺序执行的 异步任务的出现就是为了解决一些耗时量大的任务而出现的 比如下面的setTimeout
但是异步任务的缺点很明显 就是无法直接拿到异步任务的返回值 解决此问题的方法就是通过回调函数
那么我们就可以
但是假如我们另一个异步任务的值取决于上一个异步任务的返回值 那么我们也可以
假如异步任务多了起来之后 就会造成
也就是我们口中的回调地狱 promise的出现就很好的解决了这种情况
首先我们看一下promise的构造函数
创建Promise的时候 他的执行器是一个回调函数 回调函数里面有两个参数 两个参数都是函数 第一个参数一般命名为resolve 第二个参数一般命名为reject
我们可以将想要存储在Promise的值作为函数的参数传递
resolve函数用来存储运行正确时的数据 reject函数用来存储运行错误时的数据
那么之前我们那个第三个参数为回调函数的例子就可以改造为
也就是之前那些本来要用回调函数来传的数据 在promise中 可以直接调用异步代码 在异步 代码执行完之后直接调用resolve或者reject将执行结果存储到promise中
那么问题来了 我们存储到promise中的数据怎么拿呢 答案是.then()方法 then是promise的实例方法 他需要一个回调函数作为参数
注意:then方法适合用resolve存储的数据 如果存储数据的过程中出现了错误或者是通过reject 存储的数据 这种方式是读取不到的
then的第二个参数同样是一个回调函数,两个回调的函数的结构相同,不同点在于第一个回调函数会在没有异常时被调用。而第二个函数会在出现错误(或通过reject存储数据)时调用。
如果想要彻底了解promise的执行原理 可以看这篇文章www.lilichao.com/index.php/2…
除了then之外 promise还有catch方法catch和then使用方式类似,但是catch中只需要一个回调函数作为参数。catch中回调函数的作用等同于then中的第二个回调函数,会在执行出错时被调用。既然有了then的第二个参数,为什么还需要一个catch呢?两个回调函数都写到then中,会导致代码不够清晰,但是多了一个catch后立刻就变得不一样了,开发时通常会在then中编写正常运行时的代码,catch中编写出现异常后要执行的代码:
Promise中代码执行出错时(或者reject执行时),如果我们调用的是catch来处理数据,则Promise会将错误信息传递给catch的回调函数,我们便可以在catch中处理异常,同时catch回调函数的返回值会作为下一步Promise中的数据向下传递。如果我们调用了then来处理数据,同时没有传递第二个参数,这时then是不会执行的,而是将错误信息直接添加到下一步返回的Promise中,由后续的方法处理。在后续调用中如果有catch或then的第二个参数,则正常处理。如果没有,则报错。
简言之,处理Promise时,如果没有对Promise中的异常进行处理(无论是then的二参数,还是catch),则异常信息总是会封装到下一步的Promise中进行传递,直到找到异常处理的代码位置,如果一直没有处理,则报错。
这种设计方式使得我们可以在任意的位置对Promise的异常进行处理,例如有如下代码:
上例代码中,sum函数有一定的几率会出现异常,但是我们并不确定何时会出现异常,这时有了catch就变的非常的方便,因为在出现异常后所有的then在异常处理前都不会执行,所以我们可以将catch写在调用链的最后,这样无论哪一步出现异常,我们都可以在最后统一处理。像是这样
补充方法:finally finally也是Promise的实例方法之一,和then、catch不同,无论何种情况finally中的回调函数总会执行,通常我们在finally中定义一些无论Promise正确执行与否都需要处理的工作。注意,finally的回调函数不会接收任何参数,同时finally的返回值也不会成为下一步的Promise中的结果。简单说,finally只是编写一些必须要执行的代码,不会对Promise产生任何实质的影响。
还有All,AllSettled,Race等方法 可以去mdn官方文档查看