使用async/await最为js异步编程的首选方法

NODEJS从7.6版本开始开始支持async/await语法支持js异步编程,如果你还没有使用它,以下的示例将会告诉你为何要用async/await取代promise处理异步编程。

关于async/await:

  • async/await是处理异步编程的新方法,在这之前js使用的是回调函数和promise来处理异步。
  • async/await构建于promise之上,他无法同纯回调函数和nodejs风格的回调函数一同使用。
  • async/await和promise一样,是无阻塞的。
  • async/await让你的异步编程看起来就想是同步的,这是async/await最大的特点。

如下示例有中的getJSON方法它返回promise,这个promise resolve了个JSON对象,我们调用他并且打印出这个json对象,并且返回"done"

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

makeRequest()

下面是对应的async/await版本

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

makeRequest()

在此他和promise版本有如下的不同

  1. 在函数之前我们声明了关键字 async,await关键字只能在声明async关键字的函数内部使用。任何的async函数返回的都是promise,async函数的返回值作为promise resolve的值。
  2. await getJSON() 意味着只有在getJSON函数的promise resolve值得时候才会执行console方法

async/await有什么有点呢?

  1. 更简洁
  2. 更易于进行错误异常的捕获

在使用async/await的时候,你可以通过try/catch捕获同步函数异常的方式来捕获async/await的异常。如下示例 try catch将无法捕获JSON.parse的异常因为他发生在promise的内部。因此我们需要通过.catch方法才能正确的捕获异常。

const makeRequest = () => {
  try {
    getJSON()
      .then(result => {
        // this parse may fail
        const data = JSON.parse(result)
        console.log(data)
      })
      // 注释的方式来捕获异常
      // .catch((err) => {
      //   console.log(err)
      // })
  } catch (err) {
    console.log(err)
  }
}

现在我们通过try catch来捕获async await中的异常

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

3.有时候当我们请求接口的并且发起下一个请求的时候,我们需要取得上一个请求的某个数据才能发起下一个请求。

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/await的版本,它更具可读性和可维护性

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    
  }
}

4。调度值

你可能有这样的需求,你调用promise1,然后使用promise1返回的值去调用promise2,然后使用这两个promise返回的结果调用promise3,如下:

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

如果promise3并不依赖与value1,你可能会想让promise更扁平话些,以此来避免深层次的嵌套:

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

现在看起来似乎可读性提高了。这里把value1和value2放到一个数组里看起来似乎有点奇怪,除了避免promise的嵌套。相同的逻辑我们可以通过async/await来改造它。让他看起来更加的具备可读性。

const makeRequest = async () => {
  const value1 = await promise1()
  const value2 = await promise2(value1)
  return promise3(value1, value2)
}

猜你喜欢

转载自www.cnblogs.com/chargo/p/9065366.html
今日推荐