什么是async和await
你要想理解語法,可以先從兩個單詞的基本意思來進行了解.async是異步的簡寫,而await可以堪稱async wait的簡寫。明白了兩個單詞,就很好理解了async是聲明一個方法是異步的,
await是等待異步方法完成。注意的是await必須在async方法中才可以使用因為await訪問本身就會造成程序停止堵塞,所以必須在異步方法中才可以使用。
async到底起什么作用?
async是讓方法變成異步,這個很好理解,關鍵是他的返回值是什么?我們得到后如何處理?
根據以前的經驗,我們希望用return直接返回async函數的值,但是如果真是這樣,還有await什么作用,我們寫段代碼測試一下。
async function testAsync(){ return 'Hello async'; } const result = testAsync(); console.log(result);
在終端里用node執行這段代碼,你會發現輸出了Promise { ‘Hello async’ },這時候會發現它返回的是Promise。
node test.js
Promise { 'Hello async' }
async就是將函數返回值使用 Promise.resolve 包裹了下,和then中處理返回值一樣,並且async只能配合await使用
await在等什么?
await一般在等待async方法執行完畢,其實await等待的只是一個表達式,這個表達式在官方文檔里說的是Promise對象,可是它也可以接受普通值。我們寫一段代碼來驗證一下這個結果。
在程序中我們有用async的方法,也有普通的方法。最后在控制台輸出時,你會發現都可以直接輸出。
function getSomething(){ return 'something'; } async function testAsync(){ return 'Hello async'; } async function test(){ const v1=await getSomething(); const v2=await testAsync(); console.log(v1,v2); } test();
async/await同時使用
通過前面兩個例子已經分別了解async和await,我們來作個虛假的例子,看一下等待問題。這只是一個虛假的,實際項目中多是去后台請求數據,等數據回來后進行執行。
function takeLongTime() { return new Promise(resolve => { setTimeout(() => resolve("long_time_value"), 1000); }); } async function test() { const v = await takeLongTime(); console.log(v); } test();
所以調用的時候就可以這樣簡潔用 不用再then語法了
takeLongTime().then(()=>{ }).catch((err)=>{ })
項目應用 異步的數據同步化
import { subPicture } from '@/api/user' // async await 基於promise 所以 這里的封裝也是基於了這個 async getJDCulbShow(i) { try { const res = await subPicture(i) if (res.ret === 0) { this.$message({ message: '成功', type: 'success' }) console.log(res) } else { this.$message({ message: res.msg, type: 'error', center: true }) } } catch (err) { console.log('獲取數據失敗', err) } } this.getJDCulbShow(formData)
使用前后的對比
// 用 promise 獲取文件內容 function getFileContent(fileName) { const promise = new Promise((resolve, reject) => { const fullFileName = path.resolve(__dirname, 'files', fileName) fs.readFile(fullFileName, (err, data) => { if (err) { reject(err) return } resolve( JSON.parse(data.toString()) ) }) }) return promise } // 使用前 // getFileContent('a.json').then(aData => { // console.log('a data', aData) // return getFileContent(aData.next) // }).then(bData => { // console.log('b data', bData) // return getFileContent(bData.next) // }).then(cData => { // console.log('c data', cData) // })
// 使用后 async function readFileData() { // 同步寫法 try { const aData = await getFileContent('a.json') console.log('a data', aData) const bData = await getFileContent(aData.next) console.log('b data', bData) const cData = await getFileContent(bData.next) console.log('c data', cData) } catch (err) { console.error(err) } }
總結
// async await 要點: // 1. await 后面可以追加 promise 對象,獲取 resolve 的值 // 2. await 必須包裹在 async 函數里面 // 3. async 函數執行返回的也是一個 promise 對象 // 4. try-catch 截獲 promise 中 reject 的值