一、什么是Promise
Promise 是异步编程的一种解决方案:
从语法上讲,promise是一个对象。
promise有三种状态:pending(等待态),fulfiled(成功态),rejected(失败态);状态一旦改变,就不会再变。创造promise实例后,它会立即执行。
二、为什么会出现Promise
在我们处理很多异步请求时,会出现这样的代码:
async1(function(){
async2(function(){
async3(function(
async4(funciton(){
async5(function(){
//...
});
});
));
});
});
看到上面的代码,真的很恶心。这就是臭名昭著的回调地狱,他会让代码臃肿,难以维护。于是乎,在ES2015的标准里,Promise的出现解决了这个问题。
三、Promise的用法
Promise是一个构造函数,自己身上有all、reject、resolve这几个眼熟的方法,原型上有then、catch等同样很眼熟的方法。
3.1、创建Promise
let p=new Promise((resolve,reject)=>{
var flag=Math.random()
setTimeout(()=>{
console.log(flag)
if(flag>0.5){
console.log("执行完成");
resolve("成功");
}else{
console.log("执行完成");
reject("失败");
}
},2000);
})
p.then((resule)=>{
console.log(resule);
}).catch((err)=>{
console.log(err)
})
解释下上面的代码:
1.Promise是一个构造函数,所以我们使用了new操作符来创建promise。
2.构造函数Promise的参数是一个函数(暂时叫它func),这个函数(func)有两个参数resolve和reject
resolve:将promise的状态从pending(等待)转换为resolved(已解决),异步操作执行成功后的回调函数。
reject:将promise的状态pending(等待)转换为rejected(已失败)异步操作执行失败后的回调函数。
3.创建后的promise有一些方法,then和catch。当然我们也可以人为的在Promise函数上添加一些满足我们自己需求的方法,方便每一个promise对象使用。
3.2、then 链式操作的用法
从上面的介绍可以看出来Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多。
then方法是将上一步返回的结果获取过来(不管是resolved还是rejected)
p.then((resule)=>{
console.log(resule);
},(err)=>{
console.log(err)
})
then方法可以接受两个函数作为参数,第一个函数是用来处理resolve的结果,第二个是可选的,用来处理reject的结果。
当然我们还可以在每一个then方法中创建新的Promise,然后将这个Promise对象返回。每一个then方法中都可以再次新创建一个Promise对象,然后返还给下一个then方法处理,这样就可以使用then方法来进行链式的调用。
3.3、catch
catch方法可以捕获Promise对象在使用catch之前的异常。
p.then((resule)=>{
console.log(resule);
}).catch((err)=>{
console.log(err)
})
其实catch是then的一个特例,相当于:
.then(null, rejection)
3.4、all
Promise.all方法用来包装许多个Promise实例,然后组成了一个新的Promise对象,新的Promise对象的状态由前面几个被包裹的Promise对象的状态决定,如果前面的Promise都被resolve了,那么新的Promise的状态也是resolve的;只要有一个Promise被reject了,那么组成的新的Promise的状态也是reject的。
let p1=new Promise(function(resolve,reject){console.log("p1");resolve("成功1");});
let p2=new Promise(function(resolve,reject){console.log("p2");resolve("成功1");});
let p3=new Promise(function(resolve,reject){console.log("p3");resolve("成功2");});
let pall=Promise.all([p1,p2,p3]);
pall.then(function(){
// 三个都成功则成功
console.log("全部成功");
},function(){
// 只要有失败,则失败
console.log("失败");
})
3.5、race
只要包裹的的Promise对象中有一个的状态发生了改变,那么组成的这个新的Promise对象的状态就是上面那个率先改变的Promise实例的状态。简单的说:谁跑的快,以谁为准执行回调。
let arr = [1, 2, 3].map(
(value) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(value);
}, value * 1000);
});
}
)
console.log(arr)
let prace = Promise.race(arr)
.then((result) => {
console.log(result);
}).catch((err) => {
console.log(err);
});
3.6、resolve
Promise.resolve方法主要是将一个值转变为一个Promise对象,然后使它具有Promise的一些方法和特性,为了满足我们一些特殊情况下的要求。
// Promise.resolve
let resolve1=[null,0,"hello",{then:function(){console.log("resolve1")}}];
resolve1.map((value)=>{
return Promise.resolve(value);
});
console.log(resolve1)
//[ null, 0, 'hello', { then: [Function: then] } ]
//resolve1
3.7、reject
Promise.reject方法和Promise.resolve方法一样,只不过通过Promise.reject方法产生的Promise对象的状态是rejected的。
let p = Promise.reject('fail');
p.catch((err) => {
console.log(err);
}); // fail
网友评论