文章目录

  • 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构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由 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.resolvePromise.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相关推荐

  1. 【ES6(2015)】Module模块

    文章目录 1. 模块化的发展 2. export 3. as 4. export default 5. import 1. 模块化的发展 随着前端的发展,web技术日趋成熟,js功能越来越多,代码量也 ...

  2. 【ES6(2015)】Iterator

    文章目录 1. 基本语法 2. Iterator 接口与 Generator 函数 MDN : 处理集合中的每个项是很常见的操作.JavaScript 提供了许多迭代集合的方法,从简单的for循环到m ...

  3. 【ES6(2015)】Reflect

    文章目录 1. 设计目的 2. 常用方法 Reflect对象与Proxy对象一样,也是ES6 为了操作对象而提供的新 API. 1. 设计目的 将Object属于语言内部的方法放到Reflect上 l ...

  4. 【ES6(2015)】Proxy

    文章目录 1. 基本语法 2. 拦截操作场景 3. 常用操作 在 ES6 标准中新增的一个非常强大的功能是 Proxy,它可以自定义一些常用行为如查找.赋值.枚举.函数调用等.通过 Proxy 这个名 ...

  5. 【ES6(2015)】Number

    文章目录 1. 二进制与八进制 2. 新增方法 3. Math扩展 1. 二进制与八进制 ES5 中进制转换: const a = 5 console.log(a.toString(2)) // 转换 ...

  6. 【ES6(2015)】RegExp

    文章目录 1. y修饰符 2. u修饰符 1. y修饰符 ES6为正则表达式添加了y修饰符,叫做"粘连"(sticky)修饰符. y修饰符的作用与g修饰符类似,也是全局匹配,后一次 ...

  7. 【ES6(2015)】String

    文章目录 1. Unicode表示法 2. 遍历器接口 3. 模板字符串 4. 扩展方法 1. Unicode表示法 ES6 加强了对 Unicode 的支持,允许采用\uxxxx形式表示一个字符,其 ...

  8. 【ES6(2015)】Map

    文章目录 1. 基本语法 2. 遍历方式 3. WeekMap ES6 提供了 Map 数据结构.它类似于对象,也是键值对的集合,但是"键"的范围不限于字符串,各种类型的值(包括对 ...

  9. 【ES6(2015)】Set

    文章目录 1. 基本语法 2. 遍历方式 3. WeakSet 在 JavaScript 里通常使用Array或Object来存储数据. 在 ES6 中,新增了数据结构 Set 和 Map,它们分别对 ...

最新文章

  1. Yii2.X 多语言-类图
  2. shields 徽标_所有徽标看起来都一样
  3. 【剑指offer】面试题26:树的子结构(Java)
  4. python绘图 条形图 直方图 饼图 箱型图 误差图 多图绘制 图表注释 三维图形
  5. python 字符串交集_集合 (Set) | 一山不容二虎的 Python 数据类型
  6. c语言图书管理系统简单代码,C语言图书管理系统代码
  7. 我的家庭私有云计划-19
  8. golang学习之远程木马demo编写
  9. 2016 CCPC东北赛区 简单三少(proA+proC+proE)
  10. matlab寻找频谱峰值,matlab – 从数据中获取FFT峰值
  11. Nature:学术造假者瑟瑟发抖,论文图像查重AI技术重拳出击
  12. 交互设计超全学习清单:3本书,2个播客,6门视频课程,8个优秀网站
  13. linux 安装bz2文件,linux下.bz2文件的安装
  14. vivox21支持html,【vivoX21评测】看完vivo X21这20个重点,我忍不住剁手_vivo X21_手机评测-中关村在线...
  15. 模数转换,你必须知道的8个经典ADC转换电路方案
  16. Docker网络、端口映射详解篇(三)
  17. 谷歌125亿美元收购摩托罗拉
  18. 自定义控件:图片轮播,点击图片进入webview
  19. 【水声通信】使用Bellohop模型产生水声信道,采用相干检测的方法进行PSK、QAM调制解调【matlab源码】
  20. dag执行 java实现_如何调用DAG拓扑重组?

热门文章

  1. layui-简单辅助元素 - 页面元素
  2. [20170410]快速找回触发器内容.txt
  3. 印度朋友手把手教你学Scala(10):Scala里的样本对象
  4. 全面认识UML类图元素
  5. 如何进入HPunix的单用户模式
  6. 如果程序员想从事网络营虚拟光驱
  7. 修复Bug大幅升级 Sun发布MySQL 5.1版
  8. IBM发布32纳米芯片技术 明年下半年量产
  9. 职场好人缘的26个细节
  10. Python3基本数据类型快速入门