聊一聊看似简单的Promise.prototype.then()方法
Promise.prototype.then()
Proise实例的then方法是定义在原型对象Promise.prototype上的,它的作用是为Promise实例添加状态改变时的回调函数。
该方法可以接收两个回调函数作为参数,其中第二个回调函数是可选的。第一个回调函数是 Promise 对象的状态变为 Resolved 时调用,第二个回调函数是 Promise 对象的状态变为 Rejected 时调用。
下面从以下几点进行说明:
then 方法返回的是一个Promise实例,但是需要注意的是并不是原来调用它的那个Promise实例而是一个新的Promise实例。
下面用代码来说明:
let promise = new Promise( function (resolve, reject) { resolve(); console.log("promise"); }); let promise_then = promise.then(function () { console.log("promise_then"); }); promise_then.then(function () { console.log("promise_then_then") }) // 运行结果: promise promise_then promise_then_then最先打印出
promise的原因是then方法的回调函数要在所有同步任务执行完后再执行,所以会先执行console.log("promise")然后再去执行下面then方法的回调函数。当程序执行到第6行结束时,
promise和promise_then的状态如下图所示:

可见then方法返回的是一个新的promise实例,并且此时promise_then的状态为
pending。当执行完第8行时,
promise和promise_then的状态如下图所示:

可见此时promise_then的状态变为resolved,也就是说只要then方法中的程序正常执行完不报错,返回实例的状态就变为resolved(这个地方原因不是很清楚,如果有明白的,欢迎留言告知,谢谢哦)。这个时候再往下执行
promise_then.then就会打印出promise_then_then。上面的代码等价于
// ES5写法 let promise = new Promise( function (resolve, reject) { resolve(); console.log("promise"); }); promise.then(function () { console.log("promise_then"); }).then(function () { console.log("promise_then_then") }); // ES6写法 let promise = new Promise( (resolve, reject) => { resolve(); console.log("promise"); }); promise.then( () => console.log("promise_then") ).then( () => console.log("promise_then_then") );then 方法中前一个回调函数的返回值可以传递给下一个回调函数。
- 前一个回调函数的返回值是一个非promise实例时,比较简单,看一下下面的代码就很容易理解。
let promise = new Promise( function (resolve, reject) { resolve(); }); promise.then(function () { return "aaa"; }).then(function (data) { console.log(data); }); // 输出结果 "aaa"当前一个回调函数的返回值是一个promise实例时,下一个then方法的执行情况要根据这个promise实例的状态来执行。
用下面的代码来解释一下:
// 如果形参是'Resolved' -> 状态为‘Resolved’的promise实例 // 如果形参是'Rejected' -> 状态为‘Rejected’的promise实例 function createPromise(status) { var p = new Promise(function (resolve, reject) { if (status === "Resolved") { resolve() } else { reject(); } }); return p; } createPromise("Resolved").then(function () { return createPromise("Rejected"); // 返回的promise实例的状态是“Rejected” }).then(function () { console.log("前一个回调函数的返回值promise实例的状态是'Resolved'"); }, function () { console.log("前一个回调函数的返回值promise实例的状态是'Rejected'"); }); // 输出结果 "前一个回调函数的返回值promise实例的状态是'Rejected'" createPromise("Resolved").then(function () { return createPromise("Resolved"); // 返回的promise实例的状态是“Resolved” }).then(function () { console.log("前一个回调函数的返回值promise实例的状态是'Resolved'"); }, function () { console.log("前一个回调函数的返回值promise实例的状态是'Rejected'"); }); // 输出结果: "前一个回调函数的返回值promise实例的状态是'Resolved'"根据上面代码的输出结果可以清晰地看到后一个回调函数的执行情况是根据前一个回调函数返回的promise的状态来执行的,如果返回的promise实例的状态为
Resolved,那么就执行第一个函数,如果返回的promise实例的状态为Rejected,那么就执行第二个函数。
完
如果不恰当之处,欢迎指正哦 _ 。
聊一聊看似简单的Promise.prototype.then()方法的更多相关文章
- promise(3) '静态'方法
要是人没有梦想,跟咸鱼又有什么两样了?一直恐惧读源码,哪怕是一个简单的库也是读百来行遇到难点就放弃了.对于新的东西也仅仅是知道它拿来干什么,社区资源在哪里,要用时就突击文档资源使用即可.未有过深入之心 ...
- es6语法中promise的使用方法
Promise是一个构造函数,它有resolve,reject,race等静态方法;它的原型(prototype)上有then,catch方法,因此只要作为Promise的实例,都可以共享并调用Pro ...
- 简单的 Promise 实现
参考 http://www.tuicool.com/articles/RzQRV3 var PENDING = undefined, FULLFILLED = 1, REJECTED = 2; var ...
- Promise (2) 基本方法
"I'm Captain Jack Sparrow" 加勒比海盗5上映,为了表示对杰克船长的喜爱,昨天闪现了几次模仿船长的走路姿势(哈哈哈,简直妖娆). 为了周天能去看电影,要赶紧 ...
- 实现简单的promise
只考虑成功时的调用,方便理解一下promise的原理promise的例子: 1. 接下来一步步实现一个简单的promise step1:promise 接受一个函数作为构造函数的参数,是立即执行的,并 ...
- 浅析 JavaScript 中的 Function.prototype.bind() 方法
Function.prototype.bind()方法 bind() 方法的主要作用就是将函数绑定至某个对象,bind() 方法会创建一个函数,函数体内this对象的值会被绑定到传入bind() 函数 ...
- 如何用原生JS实现一个简单的promise
我又又又回来了,最近真是累的跟狗一样,急需一个大保健回复一下子精力 我现在是一边喝着红牛一边写着博客,好了好了,不扯了,回归整体好吧 先简单来说一下啥是promise吧 它是什么?Promise是一个 ...
- JavaScript 中的 Function.prototype.bind() 方法
转载自:https://www.cnblogs.com/zztt/p/4122352.html Function.prototype.bind()方法 bind() 方法的主要作用就是将函数绑定至某个 ...
- 为Promise添加finally方法支持,把小程序函数变成promise函数
// 为Promise添加finally方法支持 Promise.prototype.finally = function (callback) { let P = this.constructo ...
随机推荐
- JavaWeb02-Servlet
Servlet概述 生命周期方法: l void init(ServletConfig):出生之后(1次): l void service(ServletRequest request, Serv ...
- SpringBoot源码学习系列之SpringMVC自动配置
目录 1.ContentNegotiatingViewResolver 2.静态资源 3.自动注册 Converter, GenericConverter, and Formatter beans. ...
- ArcGIS 问题汇总
1.Arcgis10.4出现Manager打不开的情况 解决方法: 1.检查进程中是否有占用4000以及6080端口的进程,如果有关闭 2.检查进程中是否有javaw.exe这个进程,如果有就把他结束 ...
- CentOS7中安装MariaDB
什么是mariaDB? 在线安装(慢的要命) RPM离线安装(CentOS7.X) 在线安装 打开官方网站 https://mariadb.org/ 点击Download,跳转到下一页面 继续点击Do ...
- centos7关闭默认firewall,启用iptables
CentOS 7.0默认使用"firewall"防火墙 一:关闭firewall1.直接关闭防火墙systemctl stop firewalld.service 2.禁止fire ...
- Java基础IO类之字节输入输出流
一.IO流概述 1.IO流:输入输出流(Input/Output) 流是一组有顺序的,有起点和终点的字节集合,是对数据传输的总称或抽象,即数据在设备间的传输流, 流的本质是数据传输,根据数据传输特性将 ...
- day01_爬虫和数据
1.什么是爬虫 1.1.爬虫的定义 脚本,程序--->自动抓取万维网上信息的程序. 1.2.爬虫的分类 2.1.通用爬虫 通用网络爬虫 是 捜索引擎抓取系统(Baidu.Google ...
- 《手把手教你》系列练习篇之6-python+ selenium自动化测试(详细教程)
1. 简介 前面文章我们了解了如何获取元素的text属性值,和判断元素是否显示在页面(is_displayed()方法),本文我们来学习下,判断一个控件是否被选中状态. 2. 验证控件是否被选中 还是 ...
- 移动端开发语言的未来的猜想#华为云·寻找黑马程序员#【华为云技术分享】
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...
- 基于SCN增量恢复DG同步
问题描述:做scn恢复备库的测试,吭哧了几天,今天终于可以记录一下,遇到了很多坑,作为初学者可以更好地理解DG,主要先关闭备库,在主库做归档丢失备库无法同步,备库产生GAP,然后增量备份恢复备库,版本 ...