在ES6中有一个重要的对象Promise,可以被new使用。代表了未来将要发生的事,用来描述异步操作的结果。其函数内部往往会包括异步耗时的代码。
1.Promise的基本配置:
{ 挂起 成功 失败
status: 'pending | fulfilled | rejected', // status最多只能变化一次
// 状态的改变只有两种可能:pending -> fulfilled, pending -> rejected
data: undefined, // 需要携带的数据,没有默认undefined
success: null, // 成功的回调函数
failure: null, // 失败的回调函数
then: function(fn, fn2) {
this.success = fn;
this.failure = fn2;
},
resolve: function(data) { 获取一个成功状态的promise
this.data = data;
this.status = "fulfilled";
},
reject: function(data) { 获取一个失败状态的promise
this.data = data;
this.status = "rejected";
}
}
优点:异步代码用同步流程来表示。避免地狱回调(回调函数层层嵌套)。
缺点:创建后无法取消,必须设置回调函数。
2.Promise对象的创建:
var p = new Promise(function(resolve,reject) {
setTimeout(function() {
}, 2000);
}).then(function(data) => {})
.catch(function(data) => {});
catch本质上是一个特殊的then函数(第一个参数是null,第二个参数是函数),Promise的then函数和catch函数总是返回一个新的promise对象。这样我们就可以连续的then,且Promise规定:上一个then参数函数的返回值会传给下一个then的参数函数当参数,如果在then里没有显示的返回一个失败的Promise或异常出现,then函数和catch函数,总是返回一个成功的Promise。
Promise.resolve(123).then(data => { console.log(data); return Promise.resolve(456) })
// data 123
.then(data => { console.log(data); return Promise.reject(789) })
// data 456
.catch(data => { console.log(data); }) // data 789
3.Promise中的方法(还没用到过):
Promise.all([p1,p2,p3])将用于多个Promise实例包装成一个新的Promise对象。参数不一定是数组
Promise.all([p1,p2,p3])的状态分为两种情况:
只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
// 第一种情况,全是成功状态
var p1 = new Promise((resolve, reject) => { let data = 10; resolve(data) });
var p2 = new Promise((resolve, reject) => { let data = 100; resolve(data) });
var p = Promise.all([ p1, p2 ]);
p.then((datas) => { console.log(datas); }); // [10, 100]
// 第二种情况, 有一个是失败状态
var p1 = new Promise((resolve, reject) => { let data = 10; resolve(data) });
var p2 = new Promise((resolve, reject) => { let data = 100; reject(data) });
var p = Promise.all([ p1, p2 ]);
p.then((datas) => { console.log(datas); }).catch((datas) => { console.log(datas); });// 100
Promise.race 方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
Promise.race([p1,p2,p3])中只要有一个对象状态率先改变,其状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给其的返回值。
而且如果Promise.all()和Promise.race()方法的参数不是Promise对象会先调用Promise.resolve和Promise.reject方法。
var p1 = Promise.resolve('成功了');
p1.then(data => { console.log(data); }); // 成功了
var p1 = Promise.reject('失败了');
p1.then(null, data => { console.log(data); }); // 失败了
Promise对象常常用于描述异步耗时的操作。我们也会用Promise对象封装ajax和一些需要耗时的异步操作。使得代码更优雅。