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 }
