一、promise出现的原因
在promise出现以前,我们处理多个异步请求,代码大概如下:
请求1(function(请求结果1){请求2(function(请求结果2){请求3(function(请求结果3){请求4(function(请求结果4){请求5(function(请求结果5){请求6(function(请求结果3){...})})})})})})
这便是臭名昭著的回调地狱,我们需要根据第一个网络请求结果,再去执行第二个网络请求,还要对每次请求的结果进行一些处理,代码会更加臃肿,在一个团队中,代码review以及后续的维护将会是一个痛苦的过程。
回调地狱带来的负面作用有以下几点:
代码臃肿。可读性差。耦合度过高,可维护性差。代码复用性差。容易滋生 bug。只能在回调里处理异常。
出现了问题,自然就会有人去想办法。这时候,就有人思考,能不能用一种更加友好的代码组织方式,解决异步嵌套的问题。
let 请求结果1 = 请求1();let 请求结果2 = 请求2(请求结果1);let 请求结果3 = 请求3(请求结果2);let 请求结果4 = 请求4(请求结果3);let 请求结果5 = 请求5(请求结果4);
类似上面这种异步的写法,于是promise规范诞生了
二、什么是Promise
Promise是异步编程的一种解决方案,我们使用promise的时候会将函数的状态凝固,,比传统的异步解决方案(回调函数和事件)更合理,现已被es6纳入规范中。
Promise书写格式
对于上面的网络请求,Promise的常规写法:
new Promise(请求1).then(请求2(请求结果1)).then(请求3(请求结果2)).then(请求4(请求结果3)).then(请求5(请求结果4)).catch(处理异常(异常信息))
三、promise的api
resolve和reject
const promise = new Promise(function(resolve, reject) {// ... some codeif (/* 异步操作成功 */){resolve(value);} else {reject(error);}});
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数。
resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”,在异步操作成功时调用,并将异步操作的结果,作为参数传递出去。
reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”,在异步操作失败时调用,并将操作失败操作报出的错误,作为参数传递出去。
then和catch
var p = new Promise((resolve,reject)=>{resolve("success");reject("fail")})p.then(res=>{console.log(res);//成功,输出success}).catch(err=>{console.log(err);//失败,输出fail})
then触发的是resolve的状态,即成功时的状态
catch触发的是reject的状态,即失败时的反馈
四、promise封装ajax请求
function http(){return new Promise((resolve,reject)=>{$.ajax({url:"https://music.aityp.com/top/playlist?cat=华语",type:"get",success:res=>{resolve(res)},error:err=>{reject(err)}})})}http().then(res=>{console.log(res.data.playlists);})
五、Promise一些static方法
5-1 Promise.all
参考链接:理解和使用Promise.all和Promise.race
const p = Promise.all([p1, p2, p3])
只有p1,p2,p3三个状态都是fulfilled的时候,p的状态才会是fulfilled。其中有一个rejected,p的状态就会变成rejected。下面是使用实例
需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前(即使p1的结果获取的比p2要晚)。这带来一个很大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取的使用数据的场景,使用Promise.all可以很好解决这个问题。
5-2 Promise.race

顾名思义,Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
