async/await和promises的区别及怎么去使用

9 篇文章 0 订阅

1、Async/await 是建立在 Promises上的,不能被使用在普通回调以及节点回调

2、Async/await 和 Promises 很像,不阻塞

3、Async/await 代码看起来像同步代码。

语法

假设函数getJSON返回值是 Promise,并且 Promise resolves 有一些JSON 对象。我们只想调用它并且记录该JSON并且返回完成。

使用Promise

const makeRequest = () =>
  getJSON()
    .then(data => {
      console.log(data)
      return "done"
    })
    
makeRequest()

使用Async

const makeRequest = async() => {
   console.log(await getJSON())
   return "done"
}

makeRequest()

区别

  • 在函数前有一个关键字async,await关键字只能在使用async定义的函数中使用。任何一个async函数都会隐式返回一个promise,并且promise
    resolve 的值就是 return 返回的值 (例子中是”done”)
  • 不能在函数开头使用await

有哪些好处

  • 简洁的代码

使用async函数可以让代码简洁很多,不需要像Promise一样需要些then

  • 对错误的处理

Promise 中不能自定义使用 try/catch 进行错误捕获,但是在 Async/await 中可以像处理同步代码处理错误

const makeRequest = () => {
  try {
    getJSON()
      .then(result => {
        // this parse may fail
        const data = JSON.parse(result)
        console.log(data)
      })
      // uncomment this block to handle asynchronous errors
      // .catch((err) => {
      //   console.log(err)
      // })
  } catch (err) {
    console.log(err)
  }
}

Async/await

const makeRequest = async () => {
  try {
    // this parse may fail
    const data = JSON.parse(await getJSON())
    console.log(data)
  } catch (err) {
    console.log(err)
  }
}
  • 条件语句

条件语句也和错误捕获是一样的,在 Async 中也可以像平时一般使用条件语句

Promise

const makeRequest = () => {
  return getJSON()
    .then(data => {
      if (data.needsAnotherRequest) {
        return makeAnotherRequest(data)
          .then(moreData => {
            console.log(moreData)
            return moreData
          })
      } else {
        console.log(data)
        return data
      }
    })
}

Async

const makeRequest = async () => {
  const data = await getJSON()
  if (data.needsAnotherRequest) {
    const moreData = await makeAnotherRequest(data);
    console.log(moreData)
    return moreData
  } else {
    console.log(data)
    return data    
  }
}
  • 中间值

在一些场景中,也许需要 promise1 去触发 promise2 再去触发 promise3,这个时候代码应该是这样的

const makeRequest = () => {
  return promise1()
    .then(value1 => {
      // do something
      return promise2(value1)
        .then(value2 => {
          // do something          
          return promise3(value1, value2)
        })
    })
}

如过 promise3 不需要 value1,嵌套将会变得简单。如果你有强迫症,则将值1&2使用 promise.all() 分装起来。

const makeRequest = () => {
  return promise1()
    .then(value1 => {
      // do something
      return Promise.all([value1, promise2(value1)])
    })
    .then(([value1, value2]) => {
      // do something          
      return promise3(value1, value2)
    })
}

但是使用 Async 就会变得很简单

const makeRequest = async () => {
  const value1 = await promise1()
  const value2 = await promise2(value1)
  return promise3(value1, value2)
}
  • 错误堆栈

如过 Promise 连续调用,对于错误的处理是很麻烦的。你无法知道错误出在哪里。

const makeRequest = () => {
  return callAPromise()
    .then(() => callAPromise())
    .then(() => callAPromise())
    .then(() => callAPromise())
    .then(() => callAPromise())
    .then(() => {
      throw new Error("oops");
    })
}

makeRequest()
  .catch(err => {
    console.log(err);
    // output
    // Error: oops at callAPromise.then.then.then.then.then (index.js:8:13)
  })

但是对于 Async 就不一样了

const makeRequest = async () => {
  await callAPromise()
  await callAPromise()
  await callAPromise()
  await callAPromise()
  await callAPromise()
  throw new Error("oops");
}

makeRequest()
  .catch(err => {
    console.log(err);
    // output
    // Error: oops at makeRequest (index.js:7:9)
  })
  • 调试
    使用 async/await 时的一个杀手级优势是它更容易调试。调试 promise 一直很痛苦有两个原因
  1. 不能在返回表达式(无主体)的箭头函数中设置断点。
  2. 如果设置了一个断点 .then() 阻止并使用 step-over 等调试快捷方式,调试器不会移动到以下 .then() 因为它只“步进”同步代码。使用 async/await,则不需要那么多箭头函数,可以像普通的同步调用一样单步执行 await 调用。

综上所述

Async/await 是过去几年加入JavaScript的最具革命性的特性之一。它让你意识到语法混乱的承诺是什么,并提供了一个直观的替代。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值