@[toc]
一、async/await
1、定义
async: 作为一个关键字放在函数前面,用于表示函数是一个异步函数,因为async就是异步的异步,异步函数也就是意味着这个函数的执行不会阻塞后面代码的执行。
2、使用
function log(time){
setTimeout(function(){
console.log(time);
return 1;
},time)
}
async function fun(){
let a = await log(1000);
let b = await log(3000);
let c = log(2000);
console.log('a',a);// undefined
console.log(1)
}
fun();
// 立即输出 undefined 1
// 1秒后输出 1000
// 2秒后输出 2000
// 3秒后输出 3000
3、发生错误,抛出异常
如果async内部发生错误,使用 throw 抛出,catch捕获
async function demo(flag){
if(flag){
return 'hello world!!';
}else{
throw "happend err!";
}
}
demo(0).then((val)=>{
console.log(val);
}).catch((val)=>{
console.log(val);
});
console.log('first exec');
/*
first exec
happend err!
*/
4、await 的类型
await 后面可以跟任何的JS 表达式。虽然说 await 可以等很多类型的东西,但是它最主要的意图是用来等待 Promise 对象的状态被 resolved。如果await的是 promise对象会造成异步函数停止执行并且等待 promise 的解决,如果等的是正常的表达式则立即执行。
function demo(){
return new Promise((resolve, reject) => {
resolve('hello promise!');
});
}
(async function exec(){
let res = await demo();
console.log(res); //hello promise!
})();
二、promise
Promise : 对象用于表示一个异步操作的最终状态(完成或失败),以及该异步操作的结果值。它有三种状态:pending(执行中)、success(成功resolve)、rejected(失败)
- 1、Promise从pending状态改为resolved或rejected状态只会有一次,一旦变成resolve或rejected之后,这个Promise的状态就再也不会改变了。
- 2、通过resolve(retValue)传入的retValue可以是任何值,null也可以,它会传递给后面的then方法里的function去使用。通过rejected(err)传入的err理论上也是没有限制类型的,但我们一般都会传入一个Error,比如reject(new Error(“Error”))
function sleep(second) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('request done! '+ second + Math.random());
}, second);
})
}
async function bugDemo() {
console.log(await sleep(2000));
console.log(await sleep(3000));
console.log(await sleep(1000));
console.log('clear the loading~');
}
bugDemo();
/*
request done! 20000.9130830570273656
request done! 30000.5404841472398161
request done! 10000.26831404663460434
clear the loading~
*/
三、区别
- async/await是写异步代码的新方式,以前的方法有回调函数和promise
- async/await是基于promose实现的,他不能用于普通的函数
- async/await与promise一样,是非阻塞的
- async/await使得异步代码看起来像同步代码
- 使用async函数可以使代码简洁很多,不需要像promise一样需要些then,不需要写匿名函数Promise的resolve值,也不需要定义多余的data变量,害避免了嵌套代码。
- 错误处理:async/await让try/catch可以同时处理同步和异步错误。
1、案例一
使用promise
const maskRequet = () =>{
getJSON().then(res=>{
console.log(res)
})
}
使用async
const maskRequest = async() =>{
let result = await getJSON()
console.log(result)
}
2、案例二
需求:调用promise1 , 使用promise1的返回结果去调用promise2,然后使用两者的结果去调用promise3
使用promise
const maskRequest = () =>{
return promise1().then(res1=>{
return promise2(res1).then(res2=>{
return promise3(res1,res2)
})
})
}
使用async
const maskRrequest = async()=>{
const res1 = await promise1()
const res2 = await promoise2(res1)
return await promise( res1 , res2 )
}