文章目录

  • 前言
  • 一、Promise的实例方法
    • 1.Promise.prototype.then()
    • 2.Promise.prototype.catch()
    • 3.Promise.prototype.finally()
  • 总结

前言

写本《JavaScript简餐》系列文章的目的是记录在阅读学习《JavaScript高级程序设计(第4版)》一书时出现的各个知识点。虽是对读书的笔记和总结,但是希望它轻量、简洁、犀利,不会引起阅读疲劳,可以在碎片化时间和闲暇之余轻巧地沐浴一下知识点。每篇文章只针对一个小部分进行讲解式的梳理,来达到个人复习总结和分享知识的目的。


一、Promise的实例方法

1.Promise.prototype.then()

promise.prototype.then()方法是为Promise实例添加处理程序的主要方法。这个then()方法接收最多两个参数:onResolved处理程序和onRejected处理程序。这两个参数是可选的,如果提供的话,则会在Promise对象的状态分别变为resolved和rejected时执行,直接看一下具体例子:

const p1 = new Promise((resolve, reject) => {resolve();
});
const p2 = new Promise((resolve, reject) => {reject();
});p1.then(// onResolve处理程序() => {console.log("解决,Resolved!");},// onReject处理函数() => {console.log("拒绝,Rejected!");}
);
// 输出: 解决,Resolved!p2.then(// onResolve处理程序() => {console.log("解决,Resolved!");},// onReject处理函数() => {console.log("拒绝,Rejected!");}
);
// 输出: 拒绝,Rejected!

不难看出它的模式其实就是then( 处理resolve,处理reject )。then()中两个处理程序都是可选的,当传入非函数参数时会被静默忽略。如果想在then()中只写onResolved处理程序或者只写onRejected处理程序可以这么写:

p1.then(() => {console.log("解决,Resolved!");
}, null);
// 输出: 解决,Resolved!p2.then(null, () => {console.log("拒绝,Rejected!");
});
// 输出: 拒绝,Rejected!
console.log(null == undefined);

另外,还有一点要知道的是then()方法返回一个新的Promise实例:

const p1 = Promise.resolve(1);
const p2 = p1.then(() => {return 2;
});setTimeout(console.log, 0, p2); // Promise {<fulfilled>: 2}

这个新的Promise实例是基于onResolved处理程序的返回值构建的,onResolved的返回值会通过Promise.resolve()来生成新的Promise对象。

如果没有提供onResolved处理程序,那么就会用Promise.resolve()去包装上一个Promise解决后的值:

const p1 = Promise.resolve(1);
const p2 = p1.then(); // 没有传onResolved处理程序setTimeout(console.log, 0, p2); // Promise {<fulfilled>: 1}

如果没有显式的返回语句,则Promise.resolve()会包装默认值undefined。

const p1 = Promise.resolve(1);
const p2 = p1.then(() => {}); // onResolved处理程序中没有显式的返回语句setTimeout(console.log, 0, p2); // Promise {<fulfilled>: undefined}

如果抛出异常会返回拒绝的Promise对象,当然这个异常是未捕获的:

const p1 = Promise.resolve(1);
const p2 = p1.then(() => {throw "error!";
});setTimeout(console.log, 0, p2); // Promise {<rejected>: "error!"}
// Uncaught (in promise) error!

但是值得注意的是,返回错误值不会触发上面的拒绝行为,而会把错误对象包装在一个解决的期约中:

const p1 = Promise.resolve(1);
const p2 = p1.then(() => {return Error("error!");
});setTimeout(console.log, 0, p2); // Promise {<fulfilled>: Error: error!

onRejected处理程序也与onResolved类似,onRejected处理程序返回的值也会被Promise.resolve()包装。因此,拒绝处理程序在捕获错误后不抛出异常是符合期约的行为,应该返回一个解决期约。将刚刚的几种情况换成reject的情况如下:

const p1 = Promise.reject(1);
const p2 = p1.then(null, () => {return 2;
});
setTimeout(console.log, 0, p2); // Promise {<fulfilled>: 2}const p1 = Promise.reject(1);
const p2 = p1.then(); // 没有传onRejected处理程序
setTimeout(console.log, 0, p2); // Promise {<rejected>: 1}
// Uncaught (in promise) 1const p1 = Promise.reject(1);
const p2 = p1.then(null, () => {}); // onRejected处理程序中没有显式的返回语句
setTimeout(console.log, 0, p2); // Promise {<fulfilled>: undefined}const p1 = Promise.reject(1);
const p2 = p1.then(null, () => {throw "error!";
});
setTimeout(console.log, 0, p2); // Promise {<rejected>: "error!"}
// Uncaught (in promise) error!const p1 = Promise.reject(1);
const p2 = p1.then(null, () => {return Error("error!");
});
setTimeout(console.log, 0, p2); // Promise {<fulfilled>: Error: error!}

2.Promise.prototype.catch()

Promise.prototype.catch()方法用于给期约添加拒绝处理程序。这个方法只接收一个参数:onRejected处理程序。事实上这个方法就是一个语法糖,调用它就相当于调用Promise.prototype.then(null, onRejected)。如下所示:

let p = Promise.reject();
p.then(null, () => {console.log("拒绝,Rejected!"); // 拒绝,Rejected!
});
p.catch(() => {console.log("拒绝,Rejected!"); // 拒绝,Rejected!
});

同样,catch()也返回一个新的Promise实例,其行为与then()的onRejected处理程序一样。

3.Promise.prototype.finally()

Promise.prototype.finally()方法用于给Promise对象添加onFinally处理程序,这个处理程序在Promise对象的状态转换为解决或拒绝状态时都会执行。这个方法可以避免onResolved和onRejected处理程序中出现冗余代码。但onFinally处理程序没有办法知道Promise对象的状态是解决还是拒绝,所以这个方法主要用于添加清理代码。其实例如下:

let p1 = Promise.resolve();
let p2 = Promise.reject();p1.finally(console.log("Here to the finally!")); // Here to the finally!
p2.finally(console.log("Here to the finally!")); // Here to the finally!
// Uncaught (in promise) undefined

finally()方法也会返回一个新的Promise实例:

let p1 = new Promise((resolve, reject) => {});
let p2 = p1.then();setTimeout(console.log, 0, p2); // Promise {<pending>}

这个新Promise实例不同于then()或catch()方式返回的实例。因为onFinally被设计为一个状态无关的方法,所以在大多数情况下它将表现为父级Promise的传递,对于已解决或已拒绝状态都是如此:

const p1 = Promise.resolve(1);const p2 = p1.finally();
const p3 = p1.finally(() => undefined);
const p4 = p1.finally(() => {});
const p5 = p1.finally(() => Promise.resolve());
const p6 = p1.finally(() => 2);
const p7 = p1.finally(() => Promise.resolve(2));
const p8 = p1.finally(() => Error("error!"));

以上的输出将都是Promise {<fulfilled>: 1}。 如果返回的是一个待定的Promise,或者onFinally处理程序抛出了错误(显式抛出错误或者返回了一个状态为拒绝的promise),则会返回相应的期约,如下所示:

const p9 = p1.finally(() => new Promise(() => {}));
const p10 = p1.finally(() => Promise.reject());
const p11 = p1.finally(() => {throw "error!";
});setTimeout(console.log, 0, p9); // Promise {<pending>}
setTimeout(console.log, 0, p10); // Promise {<rejected>: undefined}
// Uncaught (in promise) undefined
setTimeout(console.log, 0, p11); // Promise {<rejected>: "error!"}
// Uncaught (in promise) error!

总结

以上就是今天要讲的内容,今天简单介绍了一下Promise中的几个实例方法,它们包括then()、catch()和finally()方法。下一篇我们来看一下Promise的连锁和合成。撒花~

JavaScript简餐——Promise对象的实例方法相关推荐

  1. JavaScript简餐——初见Promise

    文章目录 前言 一.Promise基础 1.Promise状态机 2.通过执行函数 控制Promise的状态 3.Promise.resolve() 4.Promise.reject() 5.同步/异 ...

  2. JavaScript简餐——关于盗用构造函数

    文章目录 前言 一.什么是盗用构造函数? 二.使用实例 三.参数传递 四.盗用构造函数的问题所在 五.总结 前言 写本<JavaScript简餐>系列文章的目的是记录在阅读学习<Ja ...

  3. JavaScript简餐——闭包

    文章目录 前言 一.闭包概念 二.闭包的副作用 三.闭包的用途 1.在函数外部读取函数的内部变量 2.利用外部函数变量缓存值 四.总结 前言 写本<JavaScript简餐>系列文章的目的 ...

  4. JavaScript简餐——初识函数

    文章目录 前言 初始函数 1.函数声明 2.函数表达式 3.箭头函数(ES6新特性) 4.使用Function构造函数 总结 前言 写本<JavaScript简餐>系列文章的目的是记录在阅 ...

  5. JavaScript简餐——类构造函数

    文章目录 前言 一.类的构造函数及其实例化 二.把类当成特殊函数 三.总结 前言 写本<JavaScript简餐>系列文章的目的是记录在阅读学习<JavaScript高级程序设计(第 ...

  6. JavaScript简餐——寄生组合继承

    文章目录 前言 一.什么是寄生组合继承? 二.寄生组合继承的基本模式 三.总结 前言 写本<JavaScript简餐>系列文章的目的是记录在阅读学习<JavaScript高级程序设计 ...

  7. JavaScript简餐——原型式继承

    文章目录 前言 一.什么是原型式继承? 二.ECMAScript5中的原型式继承 三.总结 前言 写本<JavaScript简餐>系列文章的目的是记录在阅读学习<JavaScript ...

  8. JavaScript简餐——函数尾调用优化

    文章目录 前言 一.认识尾调用优化 二.尾调用优化的条件 三.尾调用优化实例 总结 前言 写本<JavaScript简餐>系列文章的目的是记录在阅读学习<JavaScript高级程序 ...

  9. JavaScript简餐——细看函数的参数

    文章目录 前言 一.理解参数 二.箭头函数中的参数 三.总结 前言 写本<JavaScript简餐>系列文章的目的是记录在阅读学习<JavaScript高级程序设计(第4版)> ...

最新文章

  1. [20180627]测试bbed是否支持管道命令.txt
  2. TCP释放连接的四次挥手过程
  3. mongoose小试牛刀
  4. PHP文件上传,下载,Sql工具类!
  5. sourceInsight4 破解笔记(完美破解)
  6. VL09增强-冲销校验
  7. 在Spring Controller中将数据缓存到session
  8. 创造思维方法训练_数学思维方法训练课程:每日一题11.24
  9. 用户体验可视化指南pdf_R中增强可视化的初学者指南
  10. 数据共享如何改变世界_如何改变他人?“我不会去改变这个世界,我们会去改变自己”。...
  11. 如何在UE4中创建线程
  12. 整型数据类型java_Java 六种基本整型数据类型变量的取值范围
  13. scheduler 基本原理
  14. java访问修饰符_Java访问修饰符
  15. MySql命令行下导出、导入数据
  16. uniapp map 点聚合
  17. 六行shell脚本实现Android手机自动刷抖音极速版
  18. 【算法很美】递归、查找、排序 (下)
  19. 第17节 三层交换机技术—工作原理及相关命令
  20. 全触控HIFI级音质,击音Super HD II,你喜欢的样子我都有!

热门文章

  1. 简单好看的前端插件——人体时钟(honehoneclock)
  2. 再见了,深圳,你欠我的梦想,我不要了。
  3. 36亿美元!百度收购YY构建“短视频+直播”新模式
  4. 前端JS面试题简约版
  5. HDOJ 5621 KK's Point
  6. 幼儿安全消防知识教案
  7. 会议技术发展与高清视频会议系统
  8. mysql数据data怎么恢复_利用data文件恢复MySQL数据库
  9. contos 7新手上路之四:使用与美化
  10. 【优化调度】基于鸟群算法求解车间调度问题Matlab源码