未分类

ES6知识点梳理(6)

promise对象

特点:
1.对象的状态不受外界影响。Promise对象代表一个异步操作,有3种状态:Pending(进行中) Resolved(已完成又称fulfilled) rejected(已失败),只有异步操作结果可以决定当前的状态,任何操作都无法改变这个状态
2.只有两种可能:从Pending到resolved或从pending到rejected,只要其中一个发生,状态就会凝固,不会再变。就算已经改变,再对Promise对象添加回调函数,也会立即得到这个结果。与事件(event)不同,事件如果错过,再去监听找不到结果
缺点
1.无法取消,一旦新建就立即执行,无法中途取消
2.若不设置回调函数,Promise内部抛出错误不会反映到外部

用法

Promise对象是一个构造函数,用来生成Promise实例
eg:

1
2
3
4
5
6
7
8
var promise = new Promise(function(selove,reject){
//...some code
if(/* 异步操作成功 */){
resolve(value);
}else{
reject(error);
}
});

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject,这是两个函数,由js引擎提供。resolve函数在异步操作成功时调用,并将异步操作的结果作为参数传递出去,reject函数在失败时调用,并将异步操作报出的错误作为参数传递出去吧
Promise实例生成后,可以用then方法分别指定resolve状态和reject状态的回调函数
eg:

1
2
3
4
5
promise.then(function(value){
//success
},function(value){
//failure
})

then方法可以接受两个回调函数作为参数,第一个回调函数是promise对象的状态变为resolve时使用的,第二个(可选)是promise对象状态变为reject时调用的。两个函数都接受promise对象传出来的值作为参数。
如果调用resolve函数和reject函数时带有参数,那么这些参数会被传递给回调函数,reject函数的参数通常是error对象的实例,表示抛出的错误;resolve函数的参数除了正常的值外,还可能是另外一个Promise实例,表示异步操作的结果很有可能是一个值,也有可能是另一个一步操作
eg:

1
2
3
4
5
6
7
8
var p1 = new promise(function(resolve,reject){
//...
});
var p2 = new Promise(function(resolve,reject){
//...
resolve(p1);
})
//p1的状态决定了p2的状态

Promise.prototype.then()

Promise实例具有then方法。也就是,then方法是定义在原型对象Promise.prototype上的。then方法返回的是一个新的Promise实例。因此可以采用链式写法。

Promise.prototype.catch() (推荐catch)

Promise.prototype.catch方法是.then(null,rejection)的别名,用于指定发生错误时的回调函数。
eg:

1
2
3
4
5
6
7
getJSON("/posts.json").then(function(posts){
//...
}).catch(function(error){
console.log('发生错误',error);
});

//getJSON()方法假设为一个返回promise对象的函数,如果该对象状态变为resolved,则会调用then方法指定的回调函数。如果异步抛错,状态变为reject

ps:promise对象的错误有冒泡性质,会一直向后传递,直到被捕获为止,也就是说,错误总会被下一个catch捕获。如果不使用catch而是使用then,该错误不会被捕获,也不会传递到外层代码,导致运行后没有任何输出,错误会冒泡到最外层,成了未捕获的错误,catch方法返回的还是Promise对象,因此后边还可以接着调用then方法

promise.all()

promise.all方法用于将多个Promise实例包装成一个新的promise实例
eg:

1
var p = Promise.all([p1,p2,p3])

promise.all方法接受一个数组作为参数,p1,p2,p3都是promise对象的实例,如果不是,就会先调用下面讲到的promise.resolve方法,将参数转为Promise实例。(Promise.all方法的参数不一定是数组,但必须有itertor接口,且返回的每个成员都是promise实例)

1.有p1,p2,p3状态都变成fulfilled,p的状态才会变成fulfilled,此时p1,p2,p3的返回值组成一个数组,传递给p的回调函数。
2.p1,p2,p3但凡有一个被reject,p的状态就变为rejected,此时第一个被rejected的实例返回值会传递给p的回调函数

promise.race()

eg:

1
var p = Promise.race([p1,p2,p3]);

与promise.all方法的相同点是,将多个Promise实例包装成一个新的Promise实例,不同点是,只要p1,p2,p3中有一个改变,p的状态就跟着改变,率先改变的Promise实例的返回值,就传递给p的回调函数

promise.resolve()

将现有对象转为Promise对象,Promise.resolve方法就起到这个作用
eg:

1
var jsPromise = Promimse.resolve($.ajax('/whatever.json'))

上面的代码将jQuery对象生成的deferred对象转为新的promise对象