聊一聊看似简单的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 ...
随机推荐
- Netflix 开源 Polynote:对标 Jupyter,一个笔记本运行多种语言
谈到数据科学领域的开发工具,Jupyter 无疑是非常知名的一种.它具有灵活高效的特点,非常适合进行开发.调试.分享和教学.近日,Netflix(奈飞)居然也玩起了跨界,他们开源了一个名为 Polyn ...
- 什么是PHP Socket?
什么是 Socket? Socket 的中文翻译过来就是“套接字”.套接字是什么,我们先来看看它的英文含义:插座. Socket 就像一个电话插座,负责连通两端的电话,进行点对点通信,让电话可以进行通 ...
- TensorFlow在windows 下的安装
前言:从2015年谷歌将tensorflow开源后,这位用于深度学习的强大神器便把Caffe,Keras,Torch7等这一票人全部干掉,github上的star和fork是一路飙升,几乎是它们的总和 ...
- 2019-10-2,html作业,简历源码
<html> <head> <title>简历作业</title> </head> <body bgcolor=#cccccc> ...
- 新闻实时分析系统 SQL快速离线数据分析
1.Spark SQL概述1)Spark SQL是Spark核心功能的一部分,是在2014年4月份Spark1.0版本时发布的. 2)Spark SQL可以直接运行SQL或者HiveQL语句 3)BI ...
- AWK工具 使用介绍
第6周第5次课(4月27日) 课程内容: 9.6/9.7 awk扩展把这里面的所有练习题做一下http://www.apelearn.com/study_v2/chapter14.html 9.6/9 ...
- Android触摸反馈
事件分发 当点击事件发生时,事件最先传递给Activity,Activity会首先将事件将被所属的Window进行处理,即调用 superDispatchTouchEvent() 方法.通过观察sup ...
- VS2019提示scanf不安全问题
VS2019提示scanf不安全问题 我们现在学的就是使用scanf()语句进行输入,但是vs2019中却报错显示不安全 首先我先来说一下scanf和scanf-s的区别 scanf()函数是标准C中 ...
- linux虚拟机中FTP本地用户模式配置流程
1.首先在自己虚拟机中安装vsftpd服务,可以先去yum中下载(当然你要有本地yum仓库) 输入命令: yum install vsftpd 下载完成之后打开vsftpd服务 输入命令:syst ...
- 【IoT平台技术对接分享】如何上传正确的消息推送证书
消息推送应用实现消息推送的接口,部署证书,同时上传根证书到平台. 目前消息推送失败,很大一部分原因是证书上传不对.推荐小伙伴们使用下面的方法导出证书. 推送:平台调用应用服务器的restful接口将数 ...