Promise基本用法
Promise出现的动机是为了解决回掉函数嵌套问题而出现的,最开始由三方库实现,ES6现在将其加入了标准当中。
Promise对象是用于异步计算的。一个Promise表示了一个可能在现在,在将来,或者永远无法获取的值。一个Promise有3个可能的状态,分别是pending(初始态,未满足也未被拒绝),fulfilled(满足态,操作成功执行完毕)和rejected(拒绝态,操作失败)。
注意Promise的状态只能从pending到fulfilled或者从pending到rejected,而不能从fulfilled到rejected或者反过来。
1 | let p = new Promise((resolve, reject) => { |
Promise需要一个函数做参数,该函数有两个参数,这两个参数也是函数,分别是resolve和reject,resolve函数会在当Promise成功执行(fulfilled)之后该执行,reject函数会在当失败之后(rejected)执行。
来看一个完整的示例。
1 | let p = new Promise((resolve, reject) => { |
上面的代码中我们先定义了一个Promise,该Promise的逻辑很简单,输出'async started.'
,输出之后,执行指定的resolve
函数。
在定义了p
之后,我们链式调用了then
函数和catch
函数,简言之,这两个函数都接收一个函数作为参数,then
函数接收的函数参数表示执行成功(fulfilled)
的逻辑,catch
函数接收的函数参数表示执行失败的逻辑,具体的调用逻辑在Promise定义的时候确定(then
和catch
两个函数的参数分别是Promise中的resolve
和reject
)。
then
Promise.prototype.then()方法返回一个Promise,实际上可以有两个参数,第一个是fulfilled状态时被执行的函数,第二个是rejected状态时被执行的函数,不过第二个参数可以省略。
此外,由于then方法返回的是一个Promise,因此then方法可以是链式调用,当前一个then的参数函数返回的是一个非Promise类型的值时,该值会作为下一个then方法的参数函数的参数,如下面代码所示。
1 | let p = new Promise((resolve, reject) => { |
而当前一个then
的参数函数返回的是一个Promise类型的值时,后续紧跟的那个函数会等带该Promise值改变状态时才会被调用,就相当于后续紧跟的那个then
方法是前一个Promise对象函数调用的then一样。
1 | let p = new Promise((resolve, reject) => { |
catch
Promise.prototype.catch()方法返回一个Promise并且只处理拒绝态(rejected)。Promiess.prototype.catch(onRejected)跟调用Promiess.prototype.then(undefined, onRejected)效果是一样的。
1 | let p = new Promise((resolve, reject) => { |
all
Promise.all()方法接收一个iterabal对象,后面的处理行为类似处理单个Promise,也是链式调用then()方法和catch()方法。
1 | var p1 = Promise.resolve(3); |
由上可以看出all()方法会等待所有Promise执行完成,然后以数组的形式处理返回值。此外catch()方法的使用也类似。最后如果有一个Promise执行被拒绝了,其他Promise也会被拒绝,而且如果你的拒绝之后的所有其他Promise都不会被执行(Fail-Fast行为,参考3)。
1 | let p1 = new Promise((resolve, reject) => { |
知识点总结
- Promise的基本概念,三个状态和基本用法;
- Promise.prototype.then()方法的用法;
- Promise.prototype.catch()方法的用法;
- Promise.all()方法的用法。