Async/Await 学习与示例
es 7 提供了对 promise 对象的更好的操作,省去了很多丧心病狂的链式异步请求,promise 是回调地狱的福音,而 Async/Await 则是 promise 的天使。
另外,关于 event-loop ,请移步 Event-Loop In Js
Await
await 关键字修饰的东西只能用在 async 修饰的函数中,这就意味着,await 的出现一定会有 async 的身影。因此,await 不能工作在顶级作用域中。
await 关键字往往修饰的是 promise 对象。
1 2 | // 只能在async函数内部使用 let value = await promise |
关键词 await
可以让 JavaScript 进行等待,直到一个 promise 执行并返回它的结果,JavaScript才会继续往下执行。
Async
async 用来修饰函数,可以用来修饰内部没有 await 的函数。当然,如果这个函数有 return 语句,js 会自动将返回值包装成 resolved 值(promise 对象)。例如:
1 2 3 4 | async function f() { return 1 } f().then(res => console.log(res)) // 1 |
等价于:
1 2 3 4 | async function f() { return Promise.resolve(1) } f().then(res => console.log(res)) // 1 |
示例部分:
1.promise 在 1s 之后 resolve 的例子:
1 2 3 4 5 6 7 8 | async function f() { let promise = new Promise((resolve, reject) => { setTimeout(() => resolve( 'done!' ), 1000) }) let result = await promise // 直到promise返回一个resolve值(*) console.log(result) // 1s 后打印 字符串 'done!' } f() |
2.多个 await 完成链式操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | async function showAvatar() { // read our JSON let response = await fetch( '/article/promise-chaining/user.json' ) let user = await response.json() // read github user let githubResponse = await fetch(`https: //api.github.com/users/${user.name}`) let githubUser = await githubResponse.json() // 展示头像 let img = document.createElement( 'img' ) img.src = githubUser.avatar_url img.className = 'promise-avatar-example' documenmt.body.append(img) // 等待3s await new Promise((resolve, reject) => { setTimeout(resolve, 3000) }) img.remove() return githubUser } showAvatar() |
promise 链式操作版:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | function loadJson(url) { return fetch(url) .then(response => response.json()); } function loadGithubUser(name) { return fetch(`https: //api.github.com/users/${name}`) .then(response => response.json()); } function showAvatar(githubUser) { return new Promise( function (resolve, reject) { let img = document.createElement( 'img' ); img.src = githubUser.avatar_url; img.className = "promise-avatar-example" ; document.body.append(img); setTimeout(() => { img.remove(); resolve(githubUser); }, 3000); }); } // Use them: loadJson( '/article/promise-chaining/user.json' ) .then(user => loadGithubUser(user.name)) .then(showAvatar) .then(githubUser => alert(`Finished showing ${githubUser.name}`)); // ... |
错误处理:
promise 对象可不仅仅会具有 resolved 值,还会产生 rejected 值,当遇到 rejected 的时候,我们可以用两种方式来处理。
- try - catch 捕获:
1234567
try
{
let
response = await fetch(
'/no-user-here'
)
let
user = await response.json()
}
catch
(err) {
// 在fetch和response.json中都能捕获错误
alert(err)
}
- 链式 catch 捕获:
123456789
async
function
f() {
let
response = await
new
Promise((resolve, reject) => {
setTimeout(() => {
reject(
'123'
)
}, 1000)
})
}
// f()变成了一个rejected的promise
f().
catch
(err => console.log(err))
// 1s 后打印 ‘123’
更多复杂用法详见 es7 文档。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步