「这是我参与11月更文挑战的第 2 天,活动详情查看:2021最后一次更文挑战」
Promise 能做什么
在 ES6
中上架的新特性 Promise
,完美的解决了 JS Promise 扫盲兼快速上手「上」 提出的 回调地狱。当然,该写的代码一个都不会少,但起码将回调的函数平级处理了。像下图的示例,后一个依赖于前一个,则需要包装成 Promise
对象返回
Promise 常规初始化
在 js 中,Promise
可以使用 new
操作符获取一个新的实例。这也是常规的使用方法
let p = new Promise((resolve, reject) => {
// do things and change status
});
// > p
// <- Promise {<pending>}
我们需要为 Promise
传递一个匿名函数,这个函数需要有两个参数,第一个参数习惯命名为 resolve
,即表示此期约已解决,第二个参数习惯命名为 reject
,表示此期约已拒绝,等同于期约内部代码出现了异常,没有成功执行
在匿名函数内部执行异步代码块时(同步代码也没必要用 Promise),如 ajax
拉取数据,等请求成功执行后,我们在 ajax
的回调函数中,执行 resolve(data)
,将拿到的数据包装为已解决的期约,在接下来的 .then
中专注的做我们的业务
Promise 链式调用
链式调用的基本条件则在于有返回对象,下面的 3 个方法,他们都会将返回值包装为一个对应状态的 Promise
实例
无返回(隐式的返回 undefined
),返回数字、字符串、布尔、对象等等,都会被包装为 Promise.resolve()
对象
如果手动抛出异常,则会被包装为 Promise.reject()
对象
.then(resolve, reject)
then 接收两个函数类型的参数,第一个函数参数推荐命名为 resolve
,表示为对上一个已解决的期约回调处理,并接收其返回值;第二个函数参数推荐命名为 reject
,表示对上一个已拒绝的期约回调处理,接收其拒绝的理由
在日常使用时,会习惯省略第二个参数
如图,4个 then
链式调用,通过传递不同的返回值以及不同的处理方式,观察程序的执行结果
.catch(errMsg => {})
.catch(errMsg => {})
,捕获异常信息,然后针对这个异常做回调处理,和上面的 .then(resolve, reject)
比起来,就是 .then(null, errMsg => {})
的语法糖,catch
返回的 Promise
和 then
返回的 Promise
规则一致
.finally(() => {})
finally
并不关心上一步期约的执行状态,他都会能处理,所以并不会获取上一步的期约数据,一般是用于清理工作
正常情况下,
finally
会原封不动的将上一步的期约处理结果作为Promise
对象返回。但有一种特殊情况,即在finally
代码块中用throw
抛出异常时,会将这个异常信息包装为Promise.reject()
进行返回
原创文章,未经允许,禁止转载
-- by 安逸的咸鱼