【ES6(2015)】Promise
文章目录
- 1. 异步操作
- 2. Promise 基本语法
- 3. Promise.prototype.then()
- 4. Promise.prototype.catch()
- 5. Promise.resolve()
- 6. Promise.reject()
- 7. Promise.all()
- 8. Promise.race()
1. 异步操作
JS是单线程
单线程,即同一个时间只能处理一个任务。
为什么 JS 是单线程的?作为浏览器脚本语言,JavaScript 的主要用途是与用户互动,以及操作 DOM 。这决定了它只能是单线程,否则会带来很复杂的同步问题。比如,假定 JavaScript同时有两个线程,一个线程在某个 DOM 节点上添加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?
单线程就意味着,所有任务都需要排队,前一个任务结束,才能执行后一个任务。如果前一个任务耗时很长,那么后一个任务就不得不一直等待,于是乎,JS 设计者们把所有任分成两类,同步和异步。
- 同步:只有前一个任务执行完毕,才能执行后一个任务
- 异步:当同步任务执行到某个
WebAPI
时,就会触发异步操作,此时浏览器会单独开线程去处理这些异步任务。
console.log(1)
setTimeout(() => { // 异步任务,放入任务队列中console.log(2)
}, 0)
console.log(3)
// 1 3 2
步任务和异步任务的执行过程:
回调地狱
ajax('static/a.json', res => {console.log(res)ajax('static/b.json', res => {console.log(res)ajax('static/c.json', res => {console.log(res)})})
})
如果嵌套变多,代码层次就会变深,维护难度也随之增加。
这就被称为 “回调地狱” 或者“回调深渊”。
2. Promise 基本语法
Promise
就是为了解决“回调地狱”问题的,它可以将异步操作的处理变得很优雅。
// 创建Promise实例
const promise = new Promise(function(resolve, reject) {// ... some codeif ( /* 异步操作成功 */ ) {resolve(value)} else {reject(error)}
})
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve
和reject
。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。
- 处理结果正常的话,调用resolve(处理结果值),将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去
- 处理结果错误的话,调用reject(Error对象),将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
promise.then(function(value) {// success
}, function(error) {// failure
})
Promise 内部是有状态的(pending、fulfilled、rejected),Promise 对象根据状态来确定执行哪个方法。Promise 在实例化的时候状态是默认 pending 的,当异步操作是完成的,状态会被修改为 fulfilled,如果异步操作遇到异常,状态会被修改为 rejected,可以通过下图来看下状态的走向:
状态转化是单向的,不可逆转,已经确定的状态(fulfilled/rejected)无法转回初始状态(pending),而且只能是从 pending 到 fulfilled 或者 rejected
3. Promise.prototype.then()
var promise = new Promise(function(resolve, reject) {resolve('传递给then的值')
})
promise.then(function(value) {console.log(value)
}, function(error) {console.error(error)
})
这段代码创建一个 Promise 对象,定义了处理 onFulfilled 和 onRejected 的函数(handler),然后返回这个 Promise 对象;当执行resolve时,会进入then方法的成功回调方法。then方法的第一个方法为成功回调,第二个方法为失败的回调,参数为resolve/reject传递的参数。
4. Promise.prototype.catch()
使用 Promise 对象的 catch 方法来捕获异步操作过程中出现的任何异常。
function test() {return new Promise((resolve, reject) => {reject(new Error('es'))})
}test().catch((e) => {console.log(e.message) // es
})
reject 不会触发catch,new Error会触发catch,不建议在 Promise 内部使用 throw 来触发异常,而是使用 reject(new Error()) 的方式来做,因为 throw 的方式并没有改变 Pronise 的状态
5. Promise.resolve()
一般情况下我们都会使用 new Promise()
来创建 Promise
对象,但是除此之外我们也可以使用其他方法。
在这里,我们将会学习如何使用 Promise.resolve
和 Promise.reject
这两个静态方法。
new Promise(function(resolve) {resolve(42)
})Promise.resolve(42).then(function(value) {console.log(value)
})
Promise.resolve
作为 new Promise()
的快捷方式,在进行 Promise 对象的初始化或者编写测试代码的时候都非常方便。
6. Promise.reject()
Promise.reject(error)
是和 Promise.resolve(value)
类似的静态方法,是 new Promise()
方法的快捷方式。
new Promise(function(resolve, reject) {reject(new Error('出错了'))
})Promise.reject(new Error('Error!'))
7. Promise.all()
Promise.all
生成并返回一个新的 Promise 对象,所以它可以使用 Promise 实例的所有方法。参数传递promise数组中所有的 Promise 对象都变为resolve
的时候,该方法才会返回, 新创建的 Promise 则会使用这些 promise 的值。
如果参数中的任何一个promise为reject的话,则整个Promise.all调用会立即终止,并返回一个reject的新的 Promise 对象。
var p1 = Promise.resolve(1)
var p2 = Promise.resolve(2)
var p3 = Promise.resolve(3)
Promise.all([p1, p2, p3]).then(function(results) {console.log(results) // [1, 2, 3]
})
8. Promise.race()
Promise.race 生成并返回一个新的 Promise 对象。参数 promise 数组中的任何一个 Promise 对象如果变为 resolve 或者 reject 的话, 该函数就会返回,并使用这个 Promise 对象的值进行 resolve 或者 reject。
var p1 = Promise.resolve(1)
var p2 = Promise.resolve(2)
var p3 = Promise.resolve(3)
Promise.race([p1, p2, p3]).then(function(value) {console.log(value) // 1
})
【ES6(2015)】Promise相关推荐
- 【ES6(2015)】Module模块
文章目录 1. 模块化的发展 2. export 3. as 4. export default 5. import 1. 模块化的发展 随着前端的发展,web技术日趋成熟,js功能越来越多,代码量也 ...
- 【ES6(2015)】Iterator
文章目录 1. 基本语法 2. Iterator 接口与 Generator 函数 MDN : 处理集合中的每个项是很常见的操作.JavaScript 提供了许多迭代集合的方法,从简单的for循环到m ...
- 【ES6(2015)】Reflect
文章目录 1. 设计目的 2. 常用方法 Reflect对象与Proxy对象一样,也是ES6 为了操作对象而提供的新 API. 1. 设计目的 将Object属于语言内部的方法放到Reflect上 l ...
- 【ES6(2015)】Proxy
文章目录 1. 基本语法 2. 拦截操作场景 3. 常用操作 在 ES6 标准中新增的一个非常强大的功能是 Proxy,它可以自定义一些常用行为如查找.赋值.枚举.函数调用等.通过 Proxy 这个名 ...
- 【ES6(2015)】Number
文章目录 1. 二进制与八进制 2. 新增方法 3. Math扩展 1. 二进制与八进制 ES5 中进制转换: const a = 5 console.log(a.toString(2)) // 转换 ...
- 【ES6(2015)】RegExp
文章目录 1. y修饰符 2. u修饰符 1. y修饰符 ES6为正则表达式添加了y修饰符,叫做"粘连"(sticky)修饰符. y修饰符的作用与g修饰符类似,也是全局匹配,后一次 ...
- 【ES6(2015)】String
文章目录 1. Unicode表示法 2. 遍历器接口 3. 模板字符串 4. 扩展方法 1. Unicode表示法 ES6 加强了对 Unicode 的支持,允许采用\uxxxx形式表示一个字符,其 ...
- 【ES6(2015)】Map
文章目录 1. 基本语法 2. 遍历方式 3. WeekMap ES6 提供了 Map 数据结构.它类似于对象,也是键值对的集合,但是"键"的范围不限于字符串,各种类型的值(包括对 ...
- 【ES6(2015)】Set
文章目录 1. 基本语法 2. 遍历方式 3. WeakSet 在 JavaScript 里通常使用Array或Object来存储数据. 在 ES6 中,新增了数据结构 Set 和 Map,它们分别对 ...
最新文章
- Yii2.X 多语言-类图
- shields 徽标_所有徽标看起来都一样
- 【剑指offer】面试题26:树的子结构(Java)
- python绘图 条形图 直方图 饼图 箱型图 误差图 多图绘制 图表注释 三维图形
- python 字符串交集_集合 (Set) | 一山不容二虎的 Python 数据类型
- c语言图书管理系统简单代码,C语言图书管理系统代码
- 我的家庭私有云计划-19
- golang学习之远程木马demo编写
- 2016 CCPC东北赛区 简单三少(proA+proC+proE)
- matlab寻找频谱峰值,matlab – 从数据中获取FFT峰值
- Nature:学术造假者瑟瑟发抖,论文图像查重AI技术重拳出击
- 交互设计超全学习清单:3本书,2个播客,6门视频课程,8个优秀网站
- linux 安装bz2文件,linux下.bz2文件的安装
- vivox21支持html,【vivoX21评测】看完vivo X21这20个重点,我忍不住剁手_vivo X21_手机评测-中关村在线...
- 模数转换,你必须知道的8个经典ADC转换电路方案
- Docker网络、端口映射详解篇(三)
- 谷歌125亿美元收购摩托罗拉
- 自定义控件:图片轮播,点击图片进入webview
- 【水声通信】使用Bellohop模型产生水声信道,采用相干检测的方法进行PSK、QAM调制解调【matlab源码】
- dag执行 java实现_如何调用DAG拓扑重组?