1. 前言
- 首先說明
async/await
語法 屬于ES7
,不過到現(xiàn)在就算是es6也還算是新技術(shù)吧,技術(shù)迭代比較慢- 其實這個
async/await
也是一種語法糖
2. 是什么 what
async/await
語法 通常結(jié)合promise
使用- 也就是說也是用同步的方式來寫異步代碼
async
是異步的意思 用來聲明一個function
是異步的await
是 async wait 異步等待 ,就是等待一個異步函數(shù)執(zhí)行完成- 規(guī)定
await
只能出現(xiàn)在async
函數(shù)中
3. async 基礎(chǔ)
3.0 準備工作
function testAsy() {
"hello asy"
}
const result = testAsy()
console.log("result:",result);
- 正常函數(shù) 不寫返回值 結(jié)果是 undefined
- 運行結(jié)果
結(jié)果.png
3.1 async -無返回值
async function testAsy() {
"hello asy";
}
const result = testAsy();
console.log("result:", result);
- 返回結(jié)果變?yōu)? 空
Promise
, 證明async
會把函數(shù)結(jié)果變?yōu)?code>Promise- 運行結(jié)果
結(jié)果.png
- 既然是
pomise
了那resolve
的結(jié)果是啥呢
async function testAsy() {
"hello asy";
}
// const result = testAsy();
// console.log("result:", result);
testAsy().then(res=>{console.log("-----------------1",res)})
- 運行結(jié)果
undefined
1.pngasync
修飾的函數(shù) 是異步函數(shù)async
內(nèi)部給函數(shù)包了一層Promise.resolve()
3.2 async - 有返回值
async function testAsy() {
return "hello asy";
}
testAsy().then(res=>{console.log("-----------------1",res)})
- 函數(shù)的返回值是任何數(shù)據(jù)(數(shù)組,對象),則得到一個非空的
promise
對象,resolve
數(shù)據(jù)是返回的數(shù)據(jù)- 運行結(jié)果
結(jié)果.png
3.3 async- 返回 Promise
async function testAsy() {
return new Promise((resolve) => {
resolve("玩唄");
});
}
testAsy().then((res) => {
console.log("-----------------1", res);
});
- 直接得到返回值
- 運行結(jié)果
結(jié)果.png
3.4 總結(jié)
- async函數(shù)的返回值總是一個promise對象, 有以下三種情況
- 如果沒有寫返回值, 則得到一個空的promise對象, resolve數(shù)據(jù)是 undefined,
- 如果返回值是數(shù)據(jù),則得到一個非空的peomise對象, resolve數(shù)據(jù)是返回的數(shù)據(jù),
4. reject實現(xiàn)
- 既然有
resolve
那肯定也有reject
4.1 代碼
async function testAsy(flag) {
if(flag){
return "hello asy"
}else{
throw '拋出異常'
}
}
console.log(testAsy(true));//Promise.resolve()
console.log(testAsy(false));//Promise.reject()
4.2 結(jié)果
結(jié)果.png
5. catch
5.1 代碼
async function testAsy(flag) {
if(flag){
return "hello asy"
}else{
throw '拋出異常'
}
}
testAsy(false).then(res=>{
console.log("Res:",res);
}).catch(err=>{
console.log("捕獲錯誤:",err);
})
5.2 結(jié)果
1.png
還是通過 promise的 catch來進行錯誤捕獲
6. await catch
6.0 await
await
放在一個Promise
對象前,
會等待Promise
異步結(jié)果,
然后以返回值的形式拿到異步結(jié)果,
使異步結(jié)果更簡單方便的獲取,
- 避免了回調(diào)的嵌套結(jié)構(gòu),
- 省略了then函數(shù)調(diào)用
- 后面可以跟任何表達式
6.1 為什么await可以使用同步返回值的形式拿到異步promise的結(jié)果
await
通過阻塞進程,使同步代碼暫停執(zhí)行, 等Promise
異步任務得到結(jié)果后,繼續(xù)執(zhí)行同步指令,- 所以,(await is only valid in async function await)僅允許在異步函數(shù)中使用,
- 他只會阻塞異步函數(shù)中的同步代碼, 不會阻塞整個進程)
6.2 練習題 await 同步語法練習
- 練習
var p = new Promise(function(resolve){
setTimeout(() => {
resolve("成功")
}, 100);
})
// 正常情況下, 一般在promise對象的then方法的回調(diào)中拿到結(jié)果
p.then(function(res){ console.log(res)} );
console.log("-------------", 0)
async function fun(){
console.log(1)
var data = await p;
console.log(2)
console.log(3,data);
}
fun()
console.log(4)
輸出結(jié)果.png
- 強化題
function testWait() {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("測試wait")
},1000)
})
}
async function test() {
const r1 = await testAsy(true)
console.log("結(jié)果 wait:",r1);
const r2 = await testWait()
console.log("結(jié)果 wait:",r2);
}
test()
6.2 分析
1.testWait()本身就是返回的promise,異步的,所以不需要加async
2.使用async/await語法對比
3.await
放置在Promise
調(diào)用之前俭令,await
強制等待后面代碼執(zhí)行后德,直到Promise對象resolve部宿,得到resolve的值作為await表達式的運算結(jié)果
4.await
只能在async
函數(shù)內(nèi)部使用,用在普通函數(shù)里就會報錯
6.3 then處理
await
直接脫掉了一層then的殼 比較方便
6.4 catch
function testWait() {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("測試wait")
},1000)
})
}
async function test() {
const r1 = await testAsy(true)
console.log("結(jié)果 wait:",r1);
const r2 = await testWait()
console.log("結(jié)果 wait:",r2);
try{
let res3 = await testAsy(false)
console.log("結(jié)果-3:",res3)
} catch(error){
console.log("-------",error)
}
}
test()
其實就是結(jié)合 try{}catch{}來搞
7.react 使用
async componentDidMount(){
try{
let res1 = await axios.get("/v1/use?type=1")
console.log("結(jié)果:",res1)
} catch(error){
console.log("-------",error)
}
8. vue3 使用
async created() {
this.characters = (await getList()).data
}
9. 多異步任務并發(fā)執(zhí)行解決方案
// 異步函數(shù)用法舉例:
var fs = require("fs")
var p1 = new Promise(function(resolve){
fs.readFile("./data/a.txt",function(err,data){
resolve(data)
})
})
var p2 = new Promise(function(resolve){
fs.readFile("./data/b.txt",function(err,data){
resolve(data)
})
})
var p3 = new Promise(function(resolve){
fs.readFile("./data/c.txt",function(err,data){
resolve(data)
})
})
var p4 = new Promise(function(resolve){
fs.readFile("./data/d.txt",function(err,data){
resolve(data)
})
})
// 多異步任務并發(fā)執(zhí)行方案一: promise合并
var allP = Promise.all([p1,p2,p3,p4])
allP.then(function(res){
console.log(res.join(""))
})
// 多異步任務并發(fā)執(zhí)行方案二: 異步函數(shù)
async function getData(){
var data1 = await p1;
var data2 = await p2;
var data3 = await p3;
var data4 = await p4;
console.log(data1 + data2 + data3 + data4)
}
getData()
10. 擴展下規(guī)范的幾個階段
1.編輯草案 Editor's Draft (ED)
2.工作草案 Working Draft (WD)
3.過渡-最后通告工作草案 Transition – Last Call Working Draft (LCWD)
4.候選推薦標準 Candidate Recommendation (CR)
5.過渡-建議推薦標準 Transition – Proposed 6.Recommendations (PR)
7.推薦標準 Recommendation (REC)