聊一聊看似简单的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 ...
随机推荐
- PostGIS 存储过程调试
说明: 在使用Postgis做路径分析时需要用到数据库的存储过程,但是存储过程逻辑很复杂,很想看一下每步的执行结果. 百度了一下,发现postgresql有插件可以支持调试存储过程. 解决方案: 1. ...
- 20191019-3 alpha week 2/2 Scrum立会报告+燃尽图 03
此作业要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/9799 一.小组情况 队名:扛把子 组长:迟俊文 组员:宋晓丽 梁梦瑶 韩昊 ...
- Stream系列(二)Map方法使用
Stream 将List 里面的对象转换为新的对象 EmployeeTestCase.java package com.example.demo; import lombok.Data; import ...
- Xtrabackup 安装 参数详解
目录 安装 常用参数详解 innobackupex 相关参数 xtrabackup相关参数 安装 继Xtrabackup 介绍,本次来讲解安装和使用. Xtrabackup的RPM包下载地址: 系统版 ...
- java String比较,“==”和“equal”区别
public static void main(String[] args){ String str1 = new String("str"); String str2 = new ...
- Django REST framework(DRF)
Django REST framework(DRF) FBV与CBV CBV源码分析 Restful接口规范 DRF简单配置使用和源码解析 DRF序列化器 DRF10大接口 DRF视图集 三大组件 j ...
- sina中的附件图片处理
这样写就会频繁的创建和销毁对象 因为setPhotos这个方法调用频繁 如果在里面直接用for循环创建9个UIImageView如果因为cell重用 比如在上一个cell中本来就有UIImageVie ...
- php踩过的那些坑(5)浮点数计算
一.前方有坑 php在使用加减乘除等运算符计算浮点数的时候,经常会出现意想不到的结果,特别是关于财务数据方面的计算,给不少工程师惹了很多的麻烦.比如今天工作终于到的一个案例: $a = 2586; $ ...
- activate-power-mode,让你在Python编码中,感受炫酷的书写特效!
Atom Atom 是github专门为程序员推出的一个跨平台文本编辑器,具有简洁和直观的图形用户界面,并有很多有趣的特点:支持CSS,HTML,JavaScript等网页编程语言.说到这里大家以为我 ...
- 整合多个maven工程时Spring配置加载JDBC问题
问题叙述: 两个工程都通过JDBC访问mysql数据库,各自运行OK, 但合并成一个maven工程后,发现前一个工程访问数据库异常,貌似拿不到自己的DAO. 解决办法: 发现这两个工程的xml配置中, ...