javascript中async/await常用場景
我們開發過程中,經常會使用到Promise,它很好的解決了異步問題。但是,在業務邏輯比較復雜的情況下,單純的使用Promise並不好用。這時,我們可以使用ES7中新添加的async/await,在async標記的函數中,如果遇到await表達式,則函數會等待await標記的Promise解析完成,然后才會繼續執行下面的代碼。
那么,我們來舉幾個例子看看什么時候比較適合使用async/await:
假設我們有如下兩個方法:
function convertToBase64Data(url) { // 轉成base64格式 return new Promise( resolve => { setTimeout( () => { resolve('img'); }, 1000); }); } function saveToLocal(img) { // 保存到本地 return new Promise( resolve=> { setTimeout( () => { resolve('success'); }, 200); }); }
場景1:多個異步需要按順序:圖片處理完成然后保存在本地
用promise我們可能這樣寫:
function fn1() { return convertToBase64Data('http://1.jpg').then( base64Data => { return saveToLocal(base64Data); }) }
使用await則更簡潔,更好理解:
async function fn1() { const base64Data = await download('http://1.jpg'); const result = await saveToLocal(base64Data); return result; }
場景2:圖片需要同時處理,但是要按順序一張一張保存在本地
不使用await:
function fn2() { const promise1 = convertToBase64Data('http://1.jpg'); const promise2 = convertToBase64Data('http://1.jpg'); Promise.all([promise1,promise2]).then( datas => { saveToLocal(datas[0]).then( result1 => { saveToLocal(datas[1]).then(result2 => { console.log(result2); }) }) }) }
我們看到,回調很多,很不方便,下面是使用await:
async function fn2() { // 同時處理兩張 const promise1 = convertToBase64Data('http://1.jpg'); const promise2 = convertToBase64Data('http://2.jpg'); const [data1, data2] = await Promise.all([promise1, promise2]); // 先保存第一張 const result = await saveToLocal(data1); // 再保存第二張 const result2 = await saveToLocal(data2); }
代碼層次很清晰,很容易閱讀。
場景3:多張圖片,處理一張保存一張,然后才能處理下一張
不使用await:
// 你來寫寫看!!!
使用await:
async function fn3() { const imgUrls = ['http://1.jpg', 'http://2.jpg', 'http://3.jpg', 'http://4.jpg', 'http://5.jpg']; for (let i = 0; i < imgUrls.length; i++) { const base64Data = await convertToBase64Data(imgUrls[i]); const result = await saveToLocal(base64Data); console.log(result); } }
是不是覺得很爽?
場景4:條件語句
不使用await:
function fn4(needConvertToBase64) { return download('http://1.jpg').then( img => { if (needConvertToBase64) { return convertToBase64(img).then(base64Data => { return base64Data; }); } else { return img; } }); }
return 到讓人迷茫。下面使用await, 這就很爽:
async function fn4(needConvertToBase64) { const img = await download('http://1.jpg'); if (needConvertToBase64) { const base64Data = await convertToBase64(img); return base64Data; } return img; }
場景5: 你可能會這樣:調用方法1,使用方法1返回的結果去調用方法2,然后使用兩者的結果去調用方法3。
假設有如下業務: 獲取用戶ID,然后根據ID獲取用戶信息,然后將兩者保存在服務器。
function getUserId() { return Promise.resolve('123123'); } function getUserInfo(id) { return Promise.resolve({name: 'aaron'}); } function saveToServer(id, userInfo) { return Promise.resolve('success'); }
你的代碼很可能是這樣的:
function fn5() { return getUserId().then( id => { // 拿到id return getUserInfo(id).then( userInfo => { return saveToServer(id, userInfo); }); }); }
使用await:
async function fn5() {// 使用await const id = await getUserId(); const userInfo = await getUserInfo(id); return saveToServer(id, userInfo); }
場景6:錯誤處理
不使用await,try/catch不能捕獲saveToLocal的錯誤,convertToBase64 的Promise中,只能.catch處理,這樣錯誤處理代碼非常冗余,使代碼很復雜:
function fn6() { try { convertToBase64('http://1.jpg').then( data => { // saveToLocal可能會出錯 saveToLocal(data).then( result => { console.log(result); }); // .catch(err => { console.log(err)}); // 只能在.catch中處理 }); } catch (err) { // 這里取不到saveToLocal的錯誤 console.log(err); } }
使用await,try/catch能捕獲saveToLocal的錯誤:
async function fn6() { try { const data = await convertToBase64('http://1.jpg'); const result = await saveToLocal(data); console.log(result); } catch (err) { console.log(err); } }
轉自 https://www.jianshu.com/p/1bb680768e85