js Promise与async/await用法详解

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

在如今前后端分离盛行的时代,异步尤为重要,而用于解决异步问题的promise与async/await同样成为了es6中非常重要的内容,本文主要介绍它们的用法,讲解十分简单且好记。

异步

    let a = 0

    setTimeout(() => {
      a = 1
    }, 1000)
    
    console.log(a) // 0
复制代码

此时这个延迟就成为异步执行的了,a值还没有变1就被使用输出,我们只能得到0。

Promise

有时候我们不得不进行异步操作,比如从后台请求数据,我们需要时间,等待它得到数据后再使用。

也就是我们希望异步内容也能够类似同步一样。

Promise就是一种es6出现的异步解决方案。

Promise基本使用

  1. new Promise()内接收一个函数,入参为resolve, reject

  2. Promise内的函数将可以执行任意时长,执行到调用resolve()reject(),我们此处把它放在延迟1s后执行,此时a已经被赋值为1,因此就可以得到被赋值后的a。

  3. resolve()进入.then也就是执行成功回调,reject()进入.catch也就是手动执行错误进入捕获异常,reject()用的较少。

    let a = 0

    new Promise((resolve, reject) => {
      setTimeout(() => {
        a = 1
        resolve()
      }, 1000)
    })
      .then(() => {
        console.log(a) //1
      })
      .catch(() => {})
复制代码

Promise回调可接受入参

  1. .then中的回调函数可以存在入参,入参为resolve()手动传入,此处res便是传入的a值。
  2. .catchreject()的关系与上面两者同理,只不过变成了手动捕捉错误时的回调。
    let a = 0

    new Promise((resolve, reject) => {
      setTimeout(() => {
        a = 1
        resolve(a)
      }, 1000)
    })
      .then((res) => {
        console.log(res) //1
      })
      .catch(() => {})
复制代码

Promise可进行连续回调

  1. 第一种方式,回调函数中接受返回一个新的Promise进行下一步回调。

  2. 第二种方式,Promise.resolve(res)在res为普通数据时等同于new Promise并且resolve(res)

  3. 第三种也是最常用的,再异步回调中直接返回普通数据也可当作接受了一个新的Promise进行下一步回调

    let a = 0

    new Promise((resolve, reject) => {
      setTimeout(() => {
        a = 1
        resolve(a)
      }, 1000)
    })
      .then((res) => {
        return new Promise((resolve, reject) => {
          resolve(res)
        })
        //等同于
        //return Promise.resolve(res)
        //等同于
        //return res
      })
      .then((res) => {
        console.log(res) //1
      })
      .catch(() => {})
复制代码

async/await

Promise的回调是可以帮我们解决了异步数据延迟的问题,但是当回调次数过多时,代码将会变得不优雅且异常难以理解,这就是回调地狱问题。

因此es7出现了async/await,用于解决回调地狱问题。

async/await有一个限制就是必须在函数中使用,因此我们将代码包进一个函数,并在函数前加上async,这样我们便可以在函数中使用await关键字

    const test = async () => {
      let a = 0
      ...
    }
    
    test()
复制代码

await用在哪里呢?用在.then回调前的Promise

await后面跟着Promise,而它的返回值便是回调时resolve()传来的值,代替了回调函数,看起来代码一下子就清晰很多了。

    const test = async () => {
      let a = 0

      const res = await new Promise((resolve, reject) => {
        setTimeout(() => {
          a = 1
          resolve(a)
        }, 1000)
      })

      console.log(res) //1
    }
    
    test()
复制代码

常见异步请求方法与Promise、async/await的关系

常见异步请求方法有:fetch、jq的ajax、axios等

fetch就是基于Promise设计的,回调的形式进行请求,所以也可以结合async/await非常方便的使用,想要了解的话,详见:js fetch异步请求使用详解

jq的ajax和axios也是同理,存在回调基本都是基于Promise的,我们只要将.then之前的部分看作Promise放在await后面,用一个变量接收回调结束返回的数据即可。

尾言

如果觉得这篇文章对你有帮助的话,欢迎点赞收藏哦,有什么错误或者意见建议也可以留言,感谢~

猜你喜欢

转载自juejin.im/post/7078882164032421924