async 異步函數,以後可能會用得很廣。
1、箭頭函數: 沒有{ }時不寫return 也有傳回值
2、Promise : 異步神器,很多異步api都是基于Promise
3、new Promise().then().then().catch() :第一個then觸發條件:是 Promise() 執行個體化時resolve()觸發, 第二個及以後的then() 觸發條件是前一個then() 執行完成,并且将return值作為下一個then的參數。
4、async: 異步函數
5、await : 後面必須跟Promise對象,若非Promise,則不會攔截後面代碼執行。當promise對象resolve過後并且執行完then裡面的代碼,就執行下一步代碼,不resolve不會觸發下一行代碼執行。
需注意:如果then()中需要異步操作,不會等then中的異步執行完過後再執行下一個then()的函數。原因就是,異步函數中,沒有地方給你return給then()回調函數。解決方案是async函數。
也就是說Promise對于異步的幫助 其實很有限,.then()隻有第一個有用而已。
1 const aa = _ => new Promise((res, rej) => { // 設定aa函數傳回promise對象
2 setTimeout(function() {
3 console.log('1')
4 res('2')
5 }, 1000);
6 })
7 let bb = async function() {
8 await aa().then((res) => { // await會等待aa()執行完,并且then代碼也執行完,當然,then代碼裡面的異步操作不會執行。
9 console.log(res)
10 setTimeout(function(){
11 console.log('4') // then中的代碼執行完直接進入下一個then,這個then 其實return了undifined
12 return 'sdf'
13 }, 2000)
14 }).then(res => {
15 console.log(res) // undifined
16 })
17 console.log('3')
18 }
19 console.log(bb()) // Promise {<pending>}
// console 結果 :
Promise { <pending> }
1
2
undifined
3
4
目标:當A異步任務完成後,繼續并發n個B異步任務,使用asnyc函數實作
這兒具體是讀檔案夾,讀完後讀檔案夾中的所有檔案。
const readdir = function (path) { // 讀檔案函數
return new Promise((res, rej) => {
fs.readdir(path, (err, files) => {
if(err) res(err)
res(files)
})
})
}
const stat = function (path) { // 确認是否是檔案夾
return new Promise((res, rej) => {
fs.stat(path, (err, file) => {
if(err) res(err)
file.isDirectory() ? res('dir') :res('file') // 傳回類型結果
})
})
}
const getdirs = async function(ctx) {
let sendFiles = []
const files = await readdir(filePath) // 讀檔案夾
const promises = files.map(function(file){ // 利用map函數特性,傳回值組成新的數組,這兒并沒有用async函數,map内并不等待一個stat回來後再進行另一個stat,是同時進行的。
return stat(filePath + '/' + file)
.then(res => {
if(res === 'dir') sendFiles.push(file)
})
})
await Promise.all(promises) // 這兒是異步并發的關鍵,在這個位置等待所有promise對象resolve。
ctx.body = sendFiles
}