这里是一个重点大纲, promise的知识点比较复杂, 主要参考阮一峰的es6入门,具体知识点那里有非常完美的解释。
promise通俗来讲就是一个容器, 里面保存着某个未来才会结束的时事件(通常是一个一步操作)。
- promise一共有三种状态:pending,fullfilled,rejected。只有异步操作的结果可以决定pending最终的走向,结局只有一个,非fullfilled 即rejected,一旦状态改变,再也不会更改, 正是promise的含义。
resolved 并不是其中的一种状态,resolved 代指两种结局,fullfilled和rejected,但是习惯将成功的结果叫做resolved。 - 缺点???
promise 一旦开始立即执行无法取消
如果不设置回调函数,会吃掉错误,不会抛出
pending时无法知道进度以及走向 - promise构造函数接受两个参数,是两个回调函数,成功的和失败的。
promise实例生成后,可以用then()方法分别指定resolved 和rejected的回调函数。then()函数可以面条式调用,注意,在promise 内部, 总是先执行同步任务,(此处应该和微任务队列时间循环有关系,别处再议) - 优秀的做法:
一般来说,调用resolve 或者reject之后promise的任务就完成 了,有别的逻辑应该写在then()里面,而不应该写在resolve或reject后面,所以最好在resolve或者reject前面加return。做完我该做的啥也不管了。 - then方法返回的也是个promise,所以可以链式调用,前一个回调函数完成以后,会将结果作为参数传入下一个then函数,then方法要等到前一个promise状态发生变化才会被调用!
- 箭头函数在这用
- promise.prototype.catch
promise的错误抛出非常重要,如果没有使用catch指定错误出来的回调函数,promise的对象抛出的错误不会传递到外层代码,不会结束进程种植脚本的执行,即不会有任何反应。还会从错误地方继续执行下去。
promise.prototype.catch方法是.then(null,rejection)或.then(undefined,rejection)的别名,用于指定发生错误时的回调函数。
具体写法很重要去文章里找。
promise的错误具有冒泡性质,会一直向后传递, 直到遇到catch语句被捕获。 - 优秀的做法:
then()函数不写rejected回调,直接调用catch方法捕获错误。因为catch能捕获到前面的错误,并且更像同步写法。catch方法返回的还是一个promise,可以继续.then()。 - 科普:Node
node 有一个unhandledRejection事件,专门监听未捕获的rejection错误,可以在监听函数里面抛出错误,
process.on('unhandledRejection',function(err,promise){
throw err;
})
此函数接收两个参数,一个错误对象, 另一个是报错的promise对象,用来定位报错环境,node计划要废除此事件。
- promise.prototype.finally()
finally方法用于指定不管promise对象最后状态如何,都会执行的操作。(比如关闭服务器)该方法是ES2018引入标准的。
他不接受任何参数。属于then()的特例。
promise
.then(result=>{})
.catch(err=>{})
.finally(()=>{})
- promise.all()(与门)
用于将多个promise实例包装成一个promise实例
const p = Promise.all([p1,p2,p3]);
p的状态取决于参数数组(可以不必是数组,有iterator接口就行,参数值不是promise 对象也可以,会先调用Promise.resolve进行转换),全都fulfilled的情况下, p的状态才会fulfilled,否则就是rejected。
p的返回值?
(1)fulfilled 情况下,参数组的返回值组成一个数组,传递给p的回调函数;
(2)rejected情况下,第一个被rejected的实例的返回值,会传递给p的回调函数。
- Promise.race
只要有一个实例的状态发生改变,p的状态就跟着改变。那个率先改变的Promise的返回值就传递给p的回调函数。 - Promise.resolve()
将现有对象转换成promise 对象。
!在本轮事件循环末尾执行,而不是下一轮事件循环开头!
可以转换的分为三种情况:promise对象,thenable对象,没有then方法或根本不是对象。
此处的应用:如果象牙立即得到一个promise 对象,比较方便的方法就是直接调用promise.resolve方法。 - Promise.reject()
返回一个新的Promise实例,该实例的状态为rejected - Promise.try()
实际开发中,经常遇到一种情况:不知道或者不想区分函数是同步还是异步,就想用then制定下一步,用catch捕获错误:
Promise.resolve().then(f)
因为promise.then().catch()的catch只能捕获异步的错误,那么同步也会报错怎么办,事实上,Promise.try()就是模拟try catch代码块,将同步异步全都捕获。
Promise.try(()=>{}.then().catch())
网友评论