字节提前批前端⾯试题:将这段asyncawait代码翻译成Promise
如图,这道题,我轻⽽易举地说出了答案是3,2。原理的话我知道是封装成Promise,但要我翻译成Promise我还是很懵逼啊。 不得不学下怎么翻译。
不得不说,感谢这道题,让我进⼀步地深⼊了解async/await,感谢⾯试官
async/await 的基础使⽤及原理简介
async/await是es7推出的⼀套关于异步的终极解决⽅案,为什么要说他是终极解决⽅案呢?因为他实在是太好⽤了,⽽且写起来还⾮常的简单。
⼀:async/await基础语法
// 定义⼀个异步函数(假设他是⼀个异步函数)
getJSON(){
return'JSON'
}
// 在需要使⽤上⾯异步函数的函数前⾯,加上async声明,声明这是⼀个异步函数
async testAsync(){
// 在异步函数前⾯加上await,函数执⾏就会等待⽤await声明的异步函数执⾏完毕之后,在往下执⾏
await getJSON()
...剩下的代码
}
以上就是async/await最基本的⽤法。
还需要注意的⼀点就是使⽤async/await的时候,是⽆法捕获错误的,这个时候就要⽤到我们es5⾥⾯⼀个被⼤家遗忘了的try/catch,来进⾏错误的捕获:
async testAsync(){
try{
await getJSON()
}catch(err){
console.log(err)
}
...剩下的代码
}
注意:
1.async函数在声明形式上和普通函数没有区别,函数声明式,函数表达式,对象⽅法,class⽅法和箭头函数等都可以声明async函数。
2.任何⼀个await语句后⾯的 Promise 对象变为reject状态,那么整个async函数都会中断执⾏。
3.async函数返回的 Promise 对象,必须等到内部所有await命令后⾯的 Promise 对象执⾏完,才会发⽣状态改变,除⾮遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执⾏完,才会执⾏then⽅法指定的回调函数。
⼆:async/await
async这个单词⼤家应该都⽐较熟悉,他是英⽂单词‘异步’的简写,代表的意思也是异步。
async function testAsync(){
return"hello async";
}
const result =testAsync();
console.log(result);
输出结果:
Promise{<resolved>:"hello async"}
可以看出async函数,返回的是⼀个Promise对象
await是英⽂单词‘等待’的意思,代表的意思也是等待,那他等的到底是个什么东西呢?还是⼀个Promise。
三、async/await和Promise直接的转化
async/await其实是基于Promise的。async函数其实是把Promise包装了⼀下。
下⾯是⼀个async/await的写法:
getConstant(){
return1
}
async getAsyncConstant(){
return1
}
async getPromise(){
return new Promise((resolved, rejected)=>{
resolved(1)
});
}
async test(){
let a =2
let c =1
await getConstant();
let d =3
await getPromise();
let d =4
await getAsyncConstant();
return2
}
上⾯的代码其实真正的在解析执⾏的时候是这样的:
function getConstant(){
return1;
}
function getAsyncConstant(){
solve().then(function(){
return1;
});
}
function getPromise(){
solve().then(function(){
return new Promise((resolved, rejected)=>{
resolved(1);
});
});
}
test(){
solve().then(function(){
let a =2;
let c =1;
return getConstant();
}).then(function(){
let d =3;
return getPromise();
}).then(function(){
let d =4;
return getAsyncConstant();
}).then(function(){
return2;
});
}
通过上⾯的代码可以看出async/await的本⾝还是基于Promise的。
因为await本⾝返回的也是⼀个Promise,它只是把await后⾯的代码放到了await返回的Promise的.then后⾯,以此来实现的。因此回答题⽬
function getJson(){
await和async使用方法return new Promise((reslove,reject)=>{
setTimeout(function(){
console.log(2)
reslove(2)
},2000)
})
}
async function testAsync(){
await getJson()
console.log(3)
}
testAsync()
⾃⼰封装⼀下,变成啥样?
function getJson(){
return new Promise((resolve,rej)=>{
setTimeout(function(){
console.log(2)
resolve(2)
},2000)
})
}
function testAsync(){
solve().then(()=>{
return getJson()
}).then(()=>{
console.log(3)
})
}
testAsync()
你封装对了吗?
多疑的你可能就要问了。要是我把getJson函数体题改成不是返回Promise呢?如下:
function getJson(){
setTimeout(function(){
console.log(2)
},2000)
}
async function testAsync(){
await getJson()
console.log(3)
}
testAsync()
testAsync()
这样的话输出就是3,2了,但是我们刚刚的封装依旧没问题,如下所⽰
function getJson(){
setTimeout(function(){
console.log(2)
},2000)
}
function testAsync(){
solve().then(()=>{
return getJson()
}).then(()=>{
console.log(3)
})
}
testAsync()
因为return getJson()是在then⾥执⾏的,所以会返回promise。所以await等待的依旧是⼀个promise对象。有点意思,有点意思。。。
但是还有点问题 ,⽤await的时候,我们平时都是⽤来接收异步执⾏后返回的数据啊,例如
// 这个是模拟简单的⽤Promise封装ajax
function getJson(){
return new Promise((resolve,reject)=>{
setTimeout(function(){
resolve(99999)
},3000)
})
}
async function testAsync(){
let data =await getJson()
console.log(1)
console.log(data)
}
testAsync()
那,怎翻译过来呢??且看,
function getJson(){
return new Promise((resolve,reject)=>{
setTimeout(function(){
resolve(99999)
},3000)
})
}
function testAsync(){
solve().then(()=>{
return getJson()
}).then((res)=>{
let data = res
console.log(1)
console.log(data)
})
}
testAsync()
是不是感觉so easy
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论