前言
学前端基础的时候不太理解promise怎么解决回调函数,懂了之后需要知识输出,这不来了。
开始举例
举个例子,室友今天下午5点回来,紧接着吃晚饭30min,洗澡10min,洗衣服20min,零零碎碎的弄完之后看剧,话不多说,用代码来实现
// 吃饭操作时间
function getDinner(fn){
setTimeout(() => {
fn("吃晚饭")
}, 3000);
}
function getBath(fn){
setTimeout(() => {
fn("洗澡")
}, 1000);
}
function getWash(fn){
setTimeout(() => {
fn("洗衣服")
}, 2000);
}
function getTV(fn){
setTimeout(() => {
fn("看剧")
}, 4000);
}
// 执行
getDinner((data)=>{
console.log(data);
})
getBath((data)=>{
console.log(data);
})
getWash((data)=>{
console.log(data);
})
getTV((data)=>{
console.log(data);
})
按这种同步代码来实现,它是按执行时间快慢来操作,并且也没有达到我们想要的操作
将执行操作使用es5的回调函数
稍作修改
// 执行
getDinner((data)=>{
console.log(data);
getBath((data)=>{
console.log(data);
getWash((data)=>{
console.log(data);
getTV((data)=>{
console.log(data);
})
})
})
})
这样就顺理成章地形成了既在意料之中又在情理之外的——回调地狱
解决方式
解决回调函数产生的代码嵌套问题:
Ⅰ. promise
Ⅱ. async-await
Ⅲ. async.js库【无】
听我一个一个细细道来
Ⅰ.Promise
// 吃饭操作时间
function getDinner(){
return new Promise((resolve)=>{
setTimeout(() => {
resolve("吃晚饭")
}, 3000);
})
}
function getBath(){
return new Promise((resolve)=>{
setTimeout(() => {
resolve("洗澡")
}, 1000);
})
}
function getWash(){
return new Promise((resolve)=>{
setTimeout(() => {
resolve("洗衣服")
}, 2000);
})
}
function getTV(){
return new Promise((resolve)=>{
setTimeout(() => {
resolve("看剧")
}, 4000);
})
}
// 执行操作
getDinner().then((data)=>{
console.log(data);
return getBath()
}).then((data)=>{
console.log(data);
return getWash()
}).then((data)=>{
console.log(data);
return getTV()
}).then((data)=>{
console.log(data);
})
总结一下promise
知识点
- new一下promise的构造函数,分别异步传入调用成功
resolve
、失败reject
的回调函数 - promise规范then方法可以链式调用
- 从表面上看,Promise只是能够简化层层回调的写法,而实质上,Promise的精髓是“状态”,用维护状态、传递状态的方式来使得回调函数能够及时调用,它比传递callback函数要简单、灵活的多
Ⅱ.async-await
// 吃饭操作时间
function getDinner(){
return new Promise((resolve)=>{
setTimeout(() => {
resolve("吃晚饭")
}, 3000);
})
}
function getBath(){
return new Promise((resolve)=>{
setTimeout(() => {
resolve("洗澡")
}, 1000);
})
}
function getWash(){
return new Promise((resolve)=>{
setTimeout(() => {
resolve("洗衣服")
}, 2000);
})
}
function getTV(){
return new Promise((resolve)=>{
setTimeout(() => {
resolve("看剧")
}, 4000);
})
}
// async函数
async function getData() {
// 直接获取resolve传递出来的异步数据
// 里面书写同步代码
let dinner = await getDinner();
console.log(dinner);
let bath = await getBath();
console.log(bath);
let wash = await getWash();
console.log(wash);
let tv = await getTV();
console.log(tv);
}
// 调用执行
getData()
总结一下async-await
的知识点
- await只能在async函数中使用,不然会报错
- await后面最好是接Promise,虽然接其他值也能达到排队效果
- async函数返回的是一个Promise对象,有无值看有无return值
- async/await作用是用同步方式,执行异步操作
总结
既然选择了javascript
,就要珍惜和它相伴的日子