nodejs.cn-Node.js-入門教程:具有 Async 和 Await 的現代非同步 JavaScript
ylbtech-nodejs.cn-Node.js-入門教程:具有 Async 和 Await 的現代非同步 JavaScript |
1.返回頂部 |
具有 Async 和 Await 的現代非同步 JavaScript
目錄
介紹
JavaScript 在很短的時間內從回調發展到了 promise(ES2015),且自 ES2017 以來,非同步的 JavaScript 使用 async/await 語法甚至更加簡單。
非同步函式是 promise 和生成器的組合,基本上,它們是 promise 的更高級別的抽象。 而 async/await 建立在 promise 之上。
為什麼引入 async/await
它們減少了 promises 的樣板,且減少了 promise 鏈的“不破壞鏈條”的限制。
當 ES2015 中引入 Promise 時,它們旨在解決非同步程式碼的問題,並且確實做到了,但是在 ES2015 和 ES2017 斷開的兩年中,很明顯,promise 不可能成為最終的解決方案。
Promise 被引入了用於解決著名的回撥地獄問題,但是它們自身引入了複雜性以及語法複雜性。
它們是很好的原語
它們使程式碼看起來像是同步的,但它是非同步的並且在後臺無阻塞。
工作原理
非同步函式會返回 promise,例如以下示例:
const doSomethingAsync = () => {
return new Promise(resolve => {
setTimeout(() => resolve('做些事情'), 3000)
})
}
當要呼叫此函式時,則在前面加上await
,然後呼叫的程式碼就會停止直到 promise 被解決或被拒絕。 注意:客戶端函式必須被定義為async
。 這是一個示例:
const doSomething = async () => {
console.log(await doSomethingAsync())
}
一個簡單的示例
這是一個 async/await 的簡單示例,用於非同步地執行函式:
const doSomethingAsync = () => {
return new Promise(resolve => {
setTimeout(() => resolve('做些事情'), 3000)
})
}
const doSomething = async () => {
console.log(await doSomethingAsync())
}
console.log('之前')
doSomething()
console.log('之後')
上面的程式碼會列印以下的內容到瀏覽器的控制檯:
之前
之後
做些事情 // 3 秒之後
Promise 所有事情
在任何函式之前加上async
關鍵字意味著該函式會返回 promise。
即使沒有顯式地這樣做,它也會在內部使它返回 promise。
這就是為什麼此程式碼有效的原因:
const aFunction = async () => {
return '測試'
}
aFunction().then(alert) // 這會 alert '測試'
這與以下程式碼一樣:
const aFunction = async () => {
return Promise.resolve('測試')
}
aFunction().then(alert) // 這會 alert '測試'
程式碼更容易閱讀
如在上面的示例中所見,程式碼看起來非常簡單(相對於使用普通的 promise、鏈式和回撥函式的程式碼)。
這是一個非常簡單的示例,主要的好處要當代碼更復雜得多時才會看到。
例如,這是使用 promise 獲取並解析 JSON 資源的方法:
const getFirstUserData = () => {
return fetch('/users.json') // 獲取使用者列表
.then(response => response.json()) // 解析 JSON
.then(users => users[0]) // 選擇第一個使用者
.then(user => fetch(`/users/${user.name}`)) // 獲取使用者資料
.then(userResponse => userResponse.json()) // 解析 JSON
}
getFirstUserData()
這是使用 await/async 提供的相同功能:
const getFirstUserData = async () => {
const response = await fetch('/users.json') // 獲取使用者列表
const users = await response.json() // 解析 JSON
const user = users[0] // 選擇第一個使用者
const userResponse = await fetch(`/users/${user.name}`) // 獲取使用者資料
const userData = await userResponse.json() // 解析 JSON
return userData
}
getFirstUserData()
多個非同步函式串聯
非同步函式可以很容易地連結起來,並且語法比普通的 promise 更具可讀性:
const promiseToDoSomething = () => {
return new Promise(resolve => {
setTimeout(() => resolve('做些事情'), 10000)
})
}
const watchOverSomeoneDoingSomething = async () => {
const something = await promiseToDoSomething()
return something + ' 檢視'
}
const watchOverSomeoneWatchingSomeoneDoingSomething = async () => {
const something = await watchOverSomeoneDoingSomething()
return something + ' 再次檢視'
}
watchOverSomeoneWatchingSomeoneDoingSomething().then(res => {
console.log(res)
})
這會列印:
做些事情 檢視 再次檢視
更容易除錯
除錯 promise 很難,因為偵錯程式不會跳過非同步的程式碼。
Async/await 使這非常容易,因為對於編譯器而言,它就像同步程式碼一樣。
2、2.返回頂部 |
3.返回頂部 |
4.返回頂部 |
5.返回頂部 |
6.返回頂部 |
作者:ylbtech 出處:http://ylbtech.cnblogs.com/ 本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線,否則保留追究法律責任的權利。 |