一、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;
}
}