聊一聊看似简单的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 ...
随机推荐
- tornado install
pip install tornado Linux 安装时注意库的安装路径和执行时寻找路径是否一样 Windows 安装时注意user是否有权限 解决办法:
- PostGIS 爆管分析之找出总阀门
这个算法算是被摒弃了,但是很多自己思考过后留下的成果,虽然不用了,留着做记录. 算法目的是为了发生爆管后找到总阀门,这里分了几个步骤: 1.找到爆管点所在管段 2.通过遍历找到爆管点所有影响的阀门 3 ...
- Java Web登录界面
非常激动的开通了我的第一个博客,在这里希望大家能多多指点,相互学习. 一个简单的登录界面 首先我们先把这个登录分为三块: 一.数据库 数据库我用的是MYSQL: 二.前端 三.后台 1. 后台代码的 ...
- 2019-11-19:无返回的盲型xxe,使用带外读取数据
文章资料来源于网络,仅供参考,学习使用 复现盲型xxe 实验环境:bwapp,xxe关,注释掉了返回值 准备读取的flag.txt文件为 通过利用服务器外带数据方法步骤 1,攻击机服务器新建两个文件, ...
- day20191006假期作业收尾
国庆作业:(轻重缓急,重点代码看懂理解了.每天重心就是代码,理解代码,理解,understand the code.花时间花功夫.只要功夫深,铁杵磨成针.) 一.使用DAO设计模式操作数据库CRUD( ...
- Objective-C (OC)
1.OC 运行效率比较高,仅次于c.开发过程时,效率也比较高,不会次于java和C++: :表示继承 “{}”之间写字段或声明 }和@end之间写函数 import 相当于include 作用于和j ...
- 源码安装php7.2
`# 安装依赖包 yum install -y gcc gcc-c++ make zlib zlib-devel pcre pcre-devel \ libjpeg libjpeg-devel lib ...
- 如何使用Git命令克隆仓库代码
今天我的电脑装了新系统,刚装了Git到电脑上,突然有一个大胆的想法,以后不适用可视化工具了. 要逐步锻炼我的命令的操作能力,不能太依赖可视化工具. 今天先记录一下如何使用git命令克隆仓库代码 git ...
- 《Windows内核安全与驱动开发》 5.1&5.2 内核与应用方面的编程
<Windows内核安全与驱动开发>阅读笔记 -- 索引目录 <Windows内核安全与驱动开发> 5.1&5.2 内核与应用方面的编程 一.生成控制设备 如果一个驱 ...
- HTML+CSS的小实例
通过一个月以来对HTML5+CSS的学习.这篇随笔给大家来做一个简单的网页中常见的导航栏. 这些都称之为网页中的导航栏. 我简单的做了一个某宝和58同城的导航栏,供大家学习参考. 一.58同城导航栏: ...