前言 Promise 是一个非常简单的概念,即使你没有机会使用 Promise,你也可能阅读过一些关于 Promise 的文章。
什么是Promise
所谓 Promise,就是一个对象,用来传递异步操作的消息。它代表了某个未来才会知道结果的事件(通常是一个异步操作),并且这个事件提供统一的 API,可供进一步处理。
Promise的作用
Promise的出现主要是解决地狱回调callback hell的问题,比如你需要结果需要请求很多个接口,这些接口的参数需要另外那个的接口返回的数据作为依赖,这样就需要我们一层嵌套一层,但是有了Promise 我们就无需嵌套。
基本的 api
- Promise.resolve()
- Promise.reject()
- Promise.prototype.then()
- Promise.prototype.catch()
- Promise.all() // 所有的完成
- Promise.all([p1,p2,p3])
Promise 的价值在于使得异步代码以一个更可读的风格结构化,而不是因异步函数嵌套显得混乱不堪。接下来接触到 6 个你可能不知道的关于 Promise 的事。
开始列举之前,先看看怎么创建 Promise:
1、then() 返回一个 forked Promise(分叉的 Promise)
先来看下面两段代码有什么不同:
promise仅仅就是一维回调函数的数组。然而这两段代码并不等价, 每次调用 then() 都会返回一个 forked promise,因此,在A中如果func1中抛出异常,func2一样会执行,在B中是promise 的链式写法,操作的是func1中返回的新的 promise`,由于 func1 中抛出异常,这个 promise 被 rejected了,结果 func2 被跳过不执行了。
2、回调函数应该传递结果
再来看下边的代码会 alert 什么?
.then()里面操作的是上个返回来的新的promise。 promise期待你的回调函数或者返回同一个结果,或者返回其他结果但是会被传给下一个回调。
3、只能捕获来自上一级的异常
再再看两段代码有什么不一样:
在A中,当第一个 then 抛出异常时,第二个 then 能捕获到该异常,并会弹出 ''啊哦 抛出错误了''。这符合只捕获来自上一级异常的规则。 在B中,正确的回调函数和错误的回调函数在同一级,也就是说,尽管在回调中抛出了异常,但是这个异常不会被捕获。事实上,B中的错误回调只有在 promise 被 rejected 或者 promise 自身抛出一个异常时才会被执行。
4、错误能被恢复
在一个错误毁掉中,如果没有重新抛出错误,promise 会认为你已经恢复了该错误,promise 的状态,会重新转变为resolved,在下面的栗子中会弹出i am saved, 是因为第一个then()中的错误回调函数被注释了没有重新抛出异常,换句话说下一级无法捕获到异常。
5、Promise 能被暂停
仅仅因为你已经在一个 then() 函数中执行过代码,并不意味着你不能够暂停 promise 去做其他事情。为了暂停当前的 promise,或者要它等待另一个 promise 完成,只需要简单地在 then() 函数中返回另一个 promise。
6、resolved 状态的 Promise 不会立即执行
再再再来看最后一个栗子, 运行下面代码回弹出什么呢???
第一眼看上去像不像2,因为 promise 已经是 resolved ,then() 会立即执行(同步)。然而,promise规范要求是所有回调都是异步的,所以alert 执行时 i 的值还没有被修改,值依旧是0。