1、Promise的由来、
在Promise出现以前,处理一个异步网络请求,大概如下
// 请求 代表 一个异步网络调用。
// 请求结果 代表网络请求的响应。
请求1(function(请求结果1){
处理请求结果1
})
乍一看,好像没什么问题,但现在需求变了,需要在第一个请求的基础上,去执行第二个网络请求,代码如下。
请求1(function(请求结果1){
请求2(function(请求结果2){
处理请求结果2
})
})
再一看,好像也还行吧,但是,请看下面。
请求1(function(请求结果1){
请求2(function(请求结果2){
请求3(function(请求结果3){
请求4(function(请求结果4){
请求5(function(请求结果5){
请求6(function(请求结果3){
...
})
})
})
})
})
})
看起来是不是很熟悉,没错,这就是回调地狱了。 回调地狱代码臃肿、不易维护、复用性差、容易滋生bug。 总之,这样的代码,对人类非常不友好!!!
所以呢,针对这个异步嵌套的问题,就有人想出了能友好解决的方法,Promise就是这样诞生了。
2、什么是Promise?
Promise是一种异步编程的解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大,并且被列入了ES6规范中。
2.1 Promise常用写法
new Promise(请求1)
.then(请求2(请求结果1))
.then(请求3(请求结果2))
.then(请求4(请求结果3))
.then(请求5(请求结果4))
.catch(处理异常(异常信息))
与上面的回调函数的写法相比,Promise更为直观、更人性化,并且能够在外层函数捕获异步函数的异常信息。
2.2 常用API
首先要new一个Promise对象。
const p1 = new Promise((resolve,reject) => {
if(success){
resolve(value);//将状态改为成功
}else{
reject(value);//将状态改为失败
}
})
1、接着调用Promise对象上的方法,then
p1.then((value) => {
成功的回调
},(error) => {
失败的回调
}
)
then就是为Promise注册回调函数
(1)从中可以看出,then函数接受两个参数,两个参数为函数。第一个参数是,状态为resolve状态下的回调函数;第二个参数是,状态为reject状态下的回调函数。第二个参数不是必传的。
(2)then里面的方法,只有在Promise对象的状态为resolve或者reject才会被执行,并且接收resolve(value)的value作为参数
2、接着调用Promise对象上的方法,catch
p1
.then((value) => {
success
})
.catch((error) => {
error
})
catch就是捕获异常信息的
3、接着调用Promise对象上的方法,race
多个Promise任务同时执行,返回最先结束的Promise任务的结果,不论是成功还是失败。 简单来说,就是先到先得,近水楼台先得月。
4、接着调用Promise对象上的方法,all
多个Promise任务一起执行,如果全部成功,则返回一个新的Promise对象。 如果有一个为失败,则返回失败的Promise对象。
以上就是一些常用的API了,掌握了这几个APi也基本够用了!)
2.3 实例理解Promise
为了更好地理解Promise,这里我借用一个现实生活的例子,原文。 我们可以把 Promise 比作一个保姆,家里的一连串的事情,你只需要吩咐给他,他就能帮你做,你就可以去做其他事情了。
比如,作为一家之主的我,某一天要出门办事,但是我还要买菜做饭送到老婆单位(请理解我在家里的地位。。) 出门办的事情很重要,买菜做饭也重要。 。但我自己只能做一件事。 这时我就可以把买菜做饭的事情交给保姆,我会告诉她:
- 你先去超市买菜。
- 用超市买回来的菜做饭。
- 将做好的饭菜送到老婆单位。
- 送到单位后打电话告诉我。
上面前三个步骤是需要消耗时间的,可以看做是异步任务,用Promise的写法如下。
function 买菜(resolve,reject) {
setTimeout(function(){
resolve(['西红柿'、'鸡蛋'、'油菜']);
},3000)
}
function 做饭(resolve, reject){
setTimeout(function(){
//对做好的饭进行下一步处理。
resolve ({
主食: '米饭',
菜: ['西红柿炒鸡蛋'、'清炒油菜']
})
},3000)
}
function 送饭(resolve,reject){
//对送饭的结果进行下一步处理
resolve('老婆的么么哒');
}
function 电话通知我(){
//电话通知我后的下一步处理
给保姆加100块钱奖金;
}
现在有四个任务,需要告诉保姆任务的步骤,在Promise中就是实例Promise对象,用then注册回调函数,按时间顺序执行任务列表中的任务。
// 告诉保姆帮我做几件连贯的事情,先去超市买菜
new Promise(买菜)
//用买好的菜做饭
.then((买好的菜)=>{
return new Promise(做饭);
})
//把做好的饭送到老婆公司
.then((做好的饭)=>{
return new Promise(送饭);
})
//送完饭后打电话通知我
.then((送饭结果)=>{
电话通知我();
})
怎么样,这个例子,是不是让人茅塞顿开,瞬间觉得Promise是如此简单!)