一、Promise
为什么要有Promise:解决回调地狱的问题
什么是回调地域?
//跟以前的if条件地狱很像 // if(){ // if(){ // if(){ // } // } // } $.get("/getUser",function(res){ $.get("/getUserDetail",function(){ $.get("/getCart",function(){ $.get("/getBooks",function(){ //... }) }) }) }) //node开发:读取文件;开个服务器、接收一个请求、请求路径、访问数据库(异步回调)
(一)、Promise函数基本用法
var promise=new Promise((resolve,reject)=>{ //b 把需要执行的异步操作放在这里 $.get("/getUser",res=>{ //获取数据的异步操作已经执行完毕了,等待下一步的执行,通过执行resolve函数,告诉外界你可以执行下一步操作了 //c、告诉外界异步逻辑到这里就已经执行完毕了 resolve(res) //而执行的下一步操作,其实就是写在then的回调函数中的 }) }) //a、进入promise函数中 promise.then(res=>{ //d、执行后续的操作 console.log(res); })
(二)、promise函数实现多层回调
function f1(){ return new Promise(resolve=>{ setTimeout(()=>{ console.log('第一步'); //异步逻辑已经执行完,必须要告诉外界我执行完了 resolve(); },1000) }) } function f2(){ return new Promise(resolve=>{ setTimeout(()=>{ console.log('第二步'); //告诉外界我执行完了 resolve(); },1000) }) } f1().then(res=>{ //返回一个promise对象 return f2(); }).then(res=>{ setTimeout(()=>{ console.log('完成'); },1000) }) //第一步 //第二步 //完成
(三)、promise传参
function getUser(){ return new Promise(resolve=>{ $.get("/getUser",res=>{ //res是从服务器中接收到的数据 //把数据传到下一步操作中 //告诉外界本次的异步操作已经执行完毕了 resolve(res) }) }) } getUser().then(res=>{ //res就表示上一个异步操作返回的参数值:从服务器中获取的数据 })
(四)、promise错误处理
1、第一种方式
new Promise((resolve,reject)=>{ $.ajax({ url:"/getUser", type:"GET", success:res=>{ resolve(res); }, error:res=>{ reject(res) } }) }).then(resSuccess=>{ //成功的返回值 },resError=>{ //失败的返回值 })
2、第二种方式
new Promise((resolve,reject)=>{ $.ajax({ url:"/getUser", type:"GET", success:res=>{ resolve(res); }, error:res=>{ reject(res) } }) }).then(resSuccess=>{ //成功的返回值 }).catch(resError=>{ //失败的返回值 })
(五)、catch捕获错误
function f1(name){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ if(name=="a"){ resolve("成功"); }else{ reject("失败") } },1000) }) } f1("a").then(res=>{ var a=5; a(); //这里代码发生了错误 }).catch(res=>{ //成功的捕捉到了成功回调中的代码错误 console.log(res); })
(六)、多层异步中使用catch
new Promise((resolve,reject)=>{ setTimeout(()=>{ console.log('第一步'); resolve("第一步完成") },100) }).then(res=>{ console.log(res); //res:第一步完成 return new Promise((resolve,reject)=>{ setTimeout(()=>{ console.log('第二步'); reject('第二步失败'); },100) }) }).then(res=>{ //并不会执行到这里 console.log('第二步成功'); }).catch(res=>{ console.log(res); })
(七)、promise里面的返回值
new Promise(resolve=>{ setTimeout(()=>{ resolve("第一步"); },100) }).then(res=>{ //res:第一步 return 100; }).then(res=>{ console.log(res); //100 })
二、async
- async其实是一个promise的语法糖
-
await可以执行异步操作,但是await必须在async函数内执行
-
await操作可以有返回值,这个返回值表示promise操作成功的返回值
-
如果await里面执行的异步操作发生了reject,或者发生了错误,那么只能使用try...catch语法来进行错误处理
(一)、认识async
function f1(){ return new Promise(resolve=>{ setTimeout(()=>{ console.log('你好'); resolve(); },1000); }) } //async的实现 (async function(){ //await是表示这行代码是一个异步操作 //下面的代码会在这个异步操作之后执行 // -->这里的异步操作执行完毕其实就是reslove await f1(); console.log('第二步'); await f1(); await f1(); console.log('第三步'); })()
(二)、async处理返回值
function q(){ return new Promise((resolve)=>{ setTimeout(()=>{ resolve("你好"); },1000) }) } //因为await必须是在async函数内部的 var o1={ say:async ()=>{ console.log('say方法:'); const res = await q(); console.log(res); }, run:async function(){ console.log('run方法'); const res = await q(); console.log(res); } } //需求,先执行完毕say,再执行run var fn=async function(){ await o1.say(); await o1.run(); } fn();
(三)、async错误处理
function q(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ reject("你好"); },100) }) } (async function(){ try{ let res = await q(); console.log(res); }catch(e){ console.log(e); } })()
三、class
(一)、定义一个类
//构造函数的方式 function Person(name,age){ this.name=name; this.age=age; } var p1=new Person("王二麻子",8); //类的方式 class Student{ //构造方法 constructor(name,age){ this.name=name; this.age=age; } } var s1=new Student("爱因斯坦",88);
(二)、类的方法
function Person(){ } Person.prototype.run=()=>{ console.log('跑了'); } //类的方式 class Student{ //构造方法 constructor(age){ this.age=age; } run(){ console.log(`一个${this.age}岁的小伙子在跑步`); } } var s1=new Student(18);
(三)、添加静态方法
-
静态成员:静态属性、静态方法
-
静态属性:通过类本身来访问:Person.maxAge
-
静态方法:通过类本身来访问的一个方法:Person.born();
class Animal { constructor(){ } //这就是一个静态方法了 static born(){ console.log("小呆萌出生了") } } //访问静态方法 Animal.born();
(四)、类的继承
//父类 class Person { constructor(name){ this.name=name; } } //Student类继承自Person类 class Student extends Person { //构造方法 constructor(name,grade){ //规定:必须调用父类构造方法,如果不调用就会报错 super(name); //super关键字 //调用父类构造方法,从而给子类的实例添加了name属性 this.grade=grade; } }