Promise 的用途
在 JavaScript 的世界中,所有代码都是单线程执行的。由于这个特性,导致 JavaScript 的所有网络操作,浏览器事件,都必须是异步执行。
而 Promise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了语法,原生提供了 Promise。
所谓 Promise ,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。
本质上 Promise 是一个函数返回的对象,它代表了一个异步操作的最终完成或者失败。我们可以在它上面绑定回调函数,这样我们就不需要在一开始把回调函数作为参数传入这个函数了。
创建一个 new Promise
|
|
一个 Promise 必然处于以下几种状态之一:
- pending: 待定,初始状态,既没有被兑现,也没有被拒绝。
- fulfilled: 已兑现,意味着操作成功完成。
- rejected: 已拒绝,意味着操作失败。
resolve
函数的作用是,将 Promise 对象的状态从 “未完成” 变为 “成功” ,即从 pending 变为 resolved ,在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject
函数的作用是,将 Promise 对象的状态从 “未完成” 变为 “失败” ,即从 pending 变为 rejected ,在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
如何使用 Promise.prototype.then
待定状态的 Promise 对象要么会通过一个值被兑现(fulfilled),要么会通过一个 原因/错误 被拒绝(rejected)。当这些情况之一发生时,我们用 promise 的 then 方法排列起来的相关处理程序就会被调用。
then() 方法是为 Promise 实例添加状态改变时的回调函数,它返回一个 Promise 对象。
then方法最多需要有两个参数:Promise 的成功和失败情况的回调函数。第一个参数是 resolved 状态的回调函数,第二个参数(可选)是 rejected 状态的回调函数。
Promise的链式调用
因为 Promise.prototype.then
方法返回的是一个新生成的 promise,这个对象可以被非强制性的用来做链式调用,就像这样:
如何使用 Promise.all
Promise.all()
方法接收一个 promise 的 iterable 类型的输入,并且只返回一个 Promise 实例。
Promise.all()
实际上是一个 promise,它将一组 promise 作为输入(可迭代)。然后,当所有 promise 都执行成功 或 其中任何一个执行失败 时,它就会执行。
- 该 Promise 的 resolve 回调执行是在所有输入的 promise 的 resolve 回调都结束(即全部执行成功),或者输入的 iterable 里没有 promise 了的时候。
- 它的reject 回调执行是只要任何一个输入的 promise 的 reject 回调执行(即任何一个执行失败)或者输入不合法的 promise 就会立即抛出错误,并且 reject 的是 第一个 抛出的错误信息。
Promise.all 的使用
如何使用 Promise.race
Promise.race()
方法接收一个 promise 的 iterable 类型的输入,并且只返回一个 Promise 实例。
只要给定的迭代中的一个 promise 解决或拒绝,就采用第一个执行的 promise 的值作为它的值,从而异步地解析或拒绝(一旦堆栈为空),即 Promise.race()
方法返回的 promise 的状态与传入的 promise 的第一个 promise 执行状态相同。
如果传的迭代是空的,则返回的 promise 将永远等待。
Promise.race 的使用
例中虽然传入的顺序为 p1 > p2,但是 p1 和 p2 的执行顺序为 p2 > p1。
由于 Promise.race()
返回的 promise 的值与第一个执行的 promise 的值相同,所以例中虽然先传入 p1,但 race 的值为 p2。