资讯专栏INFORMATION COLUMN

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

seanlook / 1671人阅读

摘要:顺序并发请求使用的时候,代码执行的顺序很容易出错,比如我们要同时发起两个请求,可能会写出下面的代码在上面的代码中,我们认为,会并行执行,实际上并不会。会等待执行完之后才开始请求。

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.ucloud.cn/yun/95934.html

相关文章

  • 以图表示例的角度解读async/await

    摘要:在中,表示抽象的非阻塞异步执行。在完成之后安排代码的唯一方式是通过方法绑定回调函数。下图描述了该示例的计算过程方法中绑定的回调函数只有当成功的时候才会调用。为了处理失败的,需要通过绑定另一个回调函数。 介绍 ES7中,async/await 语法使异步promise的协调变得很简单。如果你需要以特定顺序异步获取来自多个数据库或API的数据,可以使用杂乱的promise或回调函数。asy...

    sutaking 评论0 收藏0
  • 异步Promise及Async/Await可能最完整入门攻略

    摘要:的和我们通过的原型方法拿到我们的返回值输出我延迟了毫秒后输出的输出下列的值我延迟了毫秒后输出的。有人说,我不想耦合性这么高,想先执行函数再执行,但不想用上面那种写法,可以吗,答案是当然可以。 此文只介绍Async/Await与Promise基础知识与实际用到注意的问题,将通过很多代码实例进行说明,两个实例代码是setDelay和setDelaySecond。 tips:本文系原创转自...

    lingdududu 评论0 收藏0
  • 异步解决方案----Promise与Await

    摘要:前言异步编程模式在前端开发过程中,显得越来越重要。随着新标准的到来,处理异步数据流又有了新的方案。接下来我们介绍这两种处理异步编程的方案。仍在继续执行,但执行结果将被丢弃。使得异步代码看起来像同步代码,再也没有回调函数。 前言 异步编程模式在前端开发过程中,显得越来越重要。从最开始的XHR到封装后的Ajax都在试图解决异步编程过程中的问题。随着ES6新标准的到来,处理异步数据流又有了新...

    Blackjun 评论0 收藏0
  • 异步解决方案----Promise与Await

    摘要:前言异步编程模式在前端开发过程中,显得越来越重要。随着新标准的到来,处理异步数据流又有了新的方案。接下来我们介绍这两种处理异步编程的方案。仍在继续执行,但执行结果将被丢弃。使得异步代码看起来像同步代码,再也没有回调函数。 前言 异步编程模式在前端开发过程中,显得越来越重要。从最开始的XHR到封装后的Ajax都在试图解决异步编程过程中的问题。随着ES6新标准的到来,处理异步数据流又有了新...

    Neilyo 评论0 收藏0
  • 异步解决方案----Promise与Await

    摘要:前言异步编程模式在前端开发过程中,显得越来越重要。随着新标准的到来,处理异步数据流又有了新的方案。接下来我们介绍这两种处理异步编程的方案。仍在继续执行,但执行结果将被丢弃。使得异步代码看起来像同步代码,再也没有回调函数。 前言 异步编程模式在前端开发过程中,显得越来越重要。从最开始的XHR到封装后的Ajax都在试图解决异步编程过程中的问题。随着ES6新标准的到来,处理异步数据流又有了新...

    entner 评论0 收藏0

发表评论

0条评论

seanlook

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<