一、Promise构造函数
1. 因为Promise是一个构造函数,我们先对它自身的方法和它原型上的方法进行总结,如下所示:
2. Promise的使用语法是,
var p = new Promise(function(resolve, reject) { //Promise实例化,并传入函数作参数
//...
});
3. 下面是 Promise 的3种状态,简单理解就是调用 resolve 方法,Promise状态变成 fulfilled,执行then里面的 onfulfilled 操作。其中 then 里面的函数就是我们所说的回调函数,而Promise中的其他语句是属于宏任务里的script代码,异步编程时不会受影响,正常执行!
下面用then的两个参数函数进行异步操作,示例:
var p = new Promise(function(resolve, reject){ //实例化Promise
var flag = false;
if(flag)
resolve('数据1');
else
reject('数据2');
});
p.then(function (data) { //用Promise的实例调用then方法
console.log(data); //对应resolve(),data等于其传入的参数
console.log('操作成功');
}, function (reason) { //失败状态一般不写!
console.log(reason); //对应reject(),reason等于其传入的参数
console.log('操作失败');
});
// 数据2 操作失败
另外,我们推荐使用catch方法代替then方法的第2个参数,因为他们的意义相同,都是在Promise状态为rejected时执行,如下所示:
var p = new Promise(function(resolve, reject){
var flag = false;
if(flag)
resolve('数据1');
else
reject('数据2');
});
p.then(function (data) {
console.log(data); //对应resolve(),data等于其传入的参数
console.log('操作成功');
}).catch(function (reason) { //失败状态一般不写!
console.log(reason); //对应reject(),reason等于其传入的参数
console.log('操作失败');
})
// 数据2 操作失败
二、Promise的作用
主要就是为了解决回调地狱问题,可以解决多个嵌套回调函数难以维护和控制的问题。
我们来看一个多个异步回调的例子,每隔一秒输出 1、2、3
setTimeout(function () {
console.log('1');
setTimeout(function () {
console.log('2');
setTimeout(function () {
console.log('3');
}, 1000);
}, 1000);
}, 1000);
而用Promise去实现时,效果如下:
function getStr1() { //1.将Promise实例的过程封装成函数
return new Promise(function (resolve, reject) { //2.返回Promise实例
setTimeout(function () {
resolve('1');
}, 1000);
});
}
function getStr2() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('2');
}, 1000);
});
}
function getStr3() {
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve('3');
}, 1000);
});
}
getStr1().then(function (data) { //3.实例调用对应的then方法
console.log(data);
return getStr2(); //4.return下一级的Promise实例,实现链式调用!
}).then(function (data) {
console.log(data);
return getStr3(); //
}).then(function (data) {
console.log(data);
});
三、Promise.all( )
Promise.all()用于将多个Promise实例,包装成一个新的Promise实例,
const p = Promise.all([p1, p2, p3]);
p
的状态由p1
、p2
、p3
决定,分成两种情况。
(1)只有p1
、p2
、p3
的状态都变成fulfilled
,p
的状态才会变成fulfilled
,此时p1
、p2
、p3
的返回值组成一个数组,传递给p
的回调函数。
(2)只要p1
、p2
、p3
之中有一个被rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p
的回调函数。
四、Promise.race( )
Promise.race()
方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。
const p = Promise.race([p1, p2, p3]);
只要p1
、p2
、p3
之中有一个实例率先改变状态,p
的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p
的回调函数。
【缺点】:
1. 如果不设置回调函数,Promise
内部抛出的错误,不会反应到外部。
2. 无法取消Promise
,一旦新建它就会立即执行,无法中途取消
参考资料: