JS Promise 扫盲兼快速上手「初始化+链式调用」

754 阅读3分钟

「这是我参与11月更文挑战的第 2 天,活动详情查看:2021最后一次更文挑战

Promise 能做什么

ES6 中上架的新特性 Promise,完美的解决了 JS Promise 扫盲兼快速上手「上」 提出的 回调地狱。当然,该写的代码一个都不会少,但起码将回调的函数平级处理了。像下图的示例,后一个依赖于前一个,则需要包装成 Promise 对象返回

image.png

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,表示对上一个已拒绝的期约回调处理,接收其拒绝的理由

在日常使用时,会习惯省略第二个参数

image.png

如图,4个 then 链式调用,通过传递不同的返回值以及不同的处理方式,观察程序的执行结果

.catch(errMsg => {})

.catch(errMsg => {}),捕获异常信息,然后针对这个异常做回调处理,和上面的 .then(resolve, reject) 比起来,就是 .then(null, errMsg => {}) 的语法糖,catch 返回的 Promisethen 返回的 Promise 规则一致

.finally(() => {})

finally 并不关心上一步期约的执行状态,他都会能处理,所以并不会获取上一步的期约数据,一般是用于清理工作

image.png

正常情况下,finally 会原封不动的将上一步的期约处理结果作为 Promise 对象返回。但有一种特殊情况,即在 finally 代码块中用 throw 抛出异常时,会将这个异常信息包装为 Promise.reject() 进行返回


原创文章,未经允许,禁止转载

-- by 安逸的咸鱼