ECMAScript之async、await详解

233 阅读2分钟

Promise是ECMAScript6中异步编程的解决方案,async和await是ECMAScript8中引入的针对Promise异步编程的进一步优化,让异步编程的写法完全和同步编程一样,写出来的代码即美观,优雅,又易读。如果你还不懂Promise的使用,建议先去学习一下promise,再来看这篇文章。

下面这段代码定义了一个login函数和一个fetchUserInfo函数,在onClickLogin中调用login获取token,然后调用fetchUserInfo获取用户信息,模拟我们常见的登陆过程。


/**
 * 登陆,返回token
 * @returns 
 */
function login(): Promise<string> {
  return new Promise((resolve, reject) => {
    //这里可以执行一些耗时的异步任务,比如网络请求
    //IO操作等,我们使用setTimeout来模拟
    setTimeout(() => {
      const random = Math.random() * 10
      if (random < 5) {
        resolve("ed87y65t03qczvgtw6538ikplon33u")
      } else {
        reject(new Error("login error"))
      }

    }, 500);
  })
}

interface User {
  name: string;
  age: number;
}

/**
 * 传入token获取用户信息
 */
function fetchUserInfo(token: string): Promise<User> {
  return new Promise<User>((resolve, reject) => {
    setTimeout(() => {
      if (token) {
        resolve({ name: "zhang", age: 28 })
      } else {
        reject(new Error("fetchUserInfo error"))
      }

    }, 800);

  })
}

function onClickLogin() {
  login().then(result => {
    return fetchUserInfo(result)
  }).then(result => {
    console.log(JSON.stringify(result));

  }).catch(error => {
    console.error(error.message)
  })
}

onClickLogin()

下面我们可以用async,await对调用过程做进一步的优化

async function onClickLogin() {
  try {
    const token = await login()
    const user = await fetchUserInfo(token)
    console.log(JSON.stringify(user));
  } catch (error) {
    console.error(error.message)
  }
}

优化后的代码和同步代码的写法看起来完全一致,可读性很强,await就像它的字面意义一样,需要等待一下才能获取 结果,在等待的过程先去干其它事情,等到结果返回了再来执行后面的任务。

下面总结一下async,await的用法:

1、如果一个函数返回值为Promise,那么可以用await进行优化

2、如果一个函数内部存在await调用,那么这个函数一定要用async修饰

3、async修饰的函数返回值一定只能是Promise

async function onClickLogin(): Promise<boolean> {
  try {
    const token = await login()
    const user = await fetchUserInfo(token)
    console.log(JSON.stringify(user));
    return true
  } catch (error) {
    console.error(error.message)
    return false
  }
}

我们看上面的代码,如果我们希望将登陆成功失败的结果以boolean值返回回去,onClickLogin的返回值必须是Promise,不能是boolean,并且我们发现,async修饰的函数return语句可以省略Promise,直接return true或者false就行