async/await 并行请求和错误处理

发布于 2022-11-06 20:11:35 字数 3179 浏览 190 评论 0

async 顺序

并发请求

使用 async 的时候,代码执行的顺序很容易出错,比如我们要同时发起两个请求,可能会写出下面的代码

function fetchName () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('lujs')
}, 3000)
})
}
function fetchAvatar () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('https://avatars3.githubusercontent.com/u/16317354?s=88&v=4')
}, 4000)
})
}
async fetchUser () {
const name = await fetchName()
const avatar = await fetchAvatar()
return {
name,
avatar
}
}
(async function () {
console.time('should be 7s ')
const user = await fetchUser()
console.log(user)
console.timeEnd('should be 3s ')
})()

在上面的代码中,我们认为 fetchName,fetchAvatar 会并行执行,实际上并不会。fetchAvatar 会等待 fetchName 执行完之后才开始请求。fetchUser 函数的执行时间不是三秒而是 7 秒。

要并行请求的话需要像下面这样写,fetchUserParallel 的执行时间为 4 秒。

async function fetchUserParallel () {
const namePromise = fetchName()
const avatarPromise = fetchAvatar()
return {
name: await namePromise,
avatar: await avatarPromise
}
}
(async function () {
console.time('should be 3s, but time is ')
const user = await fetchUser()
console.log(user)
console.timeEnd('should be 3s, but time is ')
console.time('should be 3s : ')
const user2 = await fetchUserParallel()
console.log(user2)
console.timeEnd('should be 3s : ')
})()

使用 Promise.all 来并发请求

function fetchList (id) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`id is : ${id}`)
}, 5000)
})
}
async function getList () {
const ary = [1, 2, 3, 4]
const list = Promise.all(
ary.map(
(id) => fetchList(id)
)
)
return await list
}
(async function () {
// 使用 promise 并发请求
console.time('should be 3s ')
const list = await getList()
console.log(list)
console.timeEnd('should be 3s ')
})()

错误获取

使用 try...catch

try {
  const user3 = await fetchUser(true)
} catch (err) {
  console.error('user3 error:', err)
}

包装 promise,使其返回统一的格式的代码

参考文章

/**
 * 包装 promise, 使其返回统一的错误格式
 * @param {Promise} promise 
 */
function to (promise) {
  return promise.then(res => [null, res]).catch(err => [err])
}
.
const [err, res] = await to(fetchUser(true))
if (err) {
  console.error('touser err:', err)
}

继续使用 catch

// 因为 async 返回的 promise 对象,所以可以使用 catch
const user4 = await fetchUser(true).catch(err => {
  console.error('user4 error:', err)
})

在线代码:https://www.wenjiangs.com/runcode?slug=n67tQz9e

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

文章
评论
29 人气
更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文