promsie是异步编程的一种解决方案,总得来说promise是一个对象,从它可以获取异步操作的消息。它具备以下两个特点:
- 对象的状态不受外界影响。promise对象代表一个异步操作,有三种状态:pending(进行中),fulfilled(已成功)和rejected(失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作无法改变这个promise。
- 一旦状态改变,就不会改变,任何时候都可以得到这个结果。promise只有两种过度状态
pending => fulfilled,pending =>rejected。
后续resolved统一只指fulfilled状态。
注意:无法取消promise,一旦新建立即执行,无法中途取消
常用用法
Promise 构造函数接受一个函数作为参数,我们可以看下示例
const promise = new Promise(function(resolve,reject){
if(成功) {
resolve(2); //将状态pending ->成功
console.log(1); // 这个会先执行,因为resolve()是在本轮事件的末尾执行,总是晚于本轮循环的同步
} else {
reject(New Error('fail')); //将状态pending ->失败
}
})
promise.then(function(value){
//success
console.log(value); //2
},function(error){
// failure
console.log(error);
})
- then方法返回的是一个新的promsie实列,所以可以采用链式写法,即then方法后面再调用then。
- 一般来说调用resolve和reject以后,Promise使命就完成了,所以建议直接return resolve或return reject;
catch
通常我们写promise,估计很多人平时都没写这个,这个因为我们无法保证这个promise实例运行正常,所以需要一个方法来指定发生错误时的回调(注意可以不是reject);
getJSON('/posts.json').then(function(posts){
// getJSON()方法返回一个 Promise 对象,resolve状态执行这个回调
console.log('resolved')
}).catch(function(error){
// Promise 对象抛出错误,就会被catch捕获
console.log('发生错误!',error)
})
promise对象错误具有冒泡性质
getJSON('/post/1.json').then(function(post) {
return getJSON(post.commentURL);
}).then(function(comments) {
// some code
}).catch(function(error) {
// 处理前面三个Promise产生的错误
});
一般来说,不要在then()方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。
// bad
promise
.then(function(data) {
// success
}, function(err) {
// error // 不可以捕获成功回调里的错误
});
// good
promise
.then(function(data) { //cb
// success
})
.catch(function(err) {
// error 可以捕获到then里面执行的错误
});
catch()方法返回的还是一个 Promise 对象,因此后面还可以接着调用then()方法。
finally
finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
finally方法注意没有参数,不依赖于Promise的执行结果,不管掐面是fulfilled还是rejected状态,都不会影响他的执行,其实本质上是then方法的特列
promise
.finally(() => {
// 语句
});
// 等同于
promise
.then(
result => {
// 语句
return result;
},
error => {
// 语句
throw error;
}
);
下面简单的讲几个常用的promise方法
- Promsie.all([p1,p2,p3]) 用于多个promise实例,包装成一个新的Promsie,接受具有 Iterator 接口,且返回的每个成员都是 Promise 实例的参数(常见就是数组)。全成功则成功,一个失败则会失败。
小提问?如果promise.all()其中中间有一个或者多个错误,我还是想执行成功后的回调,怎么办
给每个Promise实例都定义catch方法
- Promise.race([p1, p2, p3]); ,只要p1、p2、p3之中有一个实例率先改变状态,这个实例的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数
后续还有挺多的方法。