ES8(一) —— async&await

JavaScriptES6

# async和普通函数的区别

// 普通函数
function fuc() {
    return 27
}
console.log(fuc()); // 27

//async函数
async function firstAsync() {
  return 27
}

console.log(firstAsync())
// Promise {<resolved>: 27}
// 返回了一个promise对象,将27返回到resolve里面

// 相当于 -->

async function firstAsync() {
  return Promise.resolve(27)
}

firstAsync().then(val => {
  console.log(val) // 27
})

console.log(firstAsync() instanceof Promise)
// true 可以对async返回的对象进行判断
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# await

下面函数如何可以按照顺序执行?

async function firstAsync() {
  // 声明异步操作,执行完毕之后才能执行下面的函数
  let promise = new Promise((resolve,reject) => {
    setTimeout(() => {
      resolve('now it is done')
    }, 1000)
  })
  // 执行异步操作
  promise.then(val => {
    console.log(val)
  })
  
  console.log(2)
  return 3
}

firstAsync().then(val => {
  console.log(val)
})

//2
//3
//now it is done  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

使用await

async function firstAsync() {
  // 声明异步操作,执行完毕之后才能执行下面的函数
  let promise = new Promise((resolve,reject) => {
    setTimeout(() => {
      resolve('now it is done')
    }, 1000)
  })
  // 执行异步操作
  let result = await promise
  console.log(result)
  
  console.log(2)
  return 3
}

firstAsync().then(val => {
  console.log(val)
})

//now it is done
//2
//3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

await promise 是一个表达式,后面必须要跟promise对象,如果不是会自动处理成promise对象

console.log(await promise) 
//now it is done  ---有返回值
console.log(await 40) //40
console.log(await promise.resolve(40)) //40 
1
2
3
4

# async/await处理多回调异步

ES2017提供的Async/Await是标准的异步编程语法

如果遇到多回调的promise,简化可以使用async

// Promise chain
ajax('/api/url1')
    .then(value => {
        return ajax('ajax/url2')
    })
    .then(value => {
        return ajax('ajax/url3')
    })
    .then(value => {
        return ajax('ajax/url4')
    })
    .catch(error => {
        console.error(error)
    })
1
2
3
4
5
6
7
8
9
10
11
12
13
14

上面的代码可以这么写,效果和语法都是和generator是一样的,不用定义执行器,简单便捷,推荐使用。

async function main () {
    try{
        const users = await ajax('/api/users.json')
        console.log(users)
        
        const posts = await ajax('/api/posts.json')
        console.log(posts)
        
        const urls = await ajax('/api/urls.json')
        console.log(urls)
    } catch (e) {
        //捕获异常
        console.log(e)
    }
}

main()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# async和await必须配合使用

否则会报错

# 关于await使用中错误的处理

如果不对await进行错误处理,则会阻断程序执行。

await使用中,如果promise对象返回resolve,则返回什么值就是什么值,包括undefined

但是如果返回reject,则返回值返回undefined,从catch函数中可以接收到。

# 第一种处理方法:try-catch

  • 优点:简洁明了,所有报错都到catch里面处理,不需要对await返回值进行判断
  • 缺点:本身try-catch是处理同步报错的问题,如果await函数之后有报错,则无法判断报错来源
// 定义一个函数,返回promise对象
function firstAsync() {
  return new Promise((resolve,reject) => {
    const a = 0;
    if(a){
      resolve(1)
    }else{
      reject(2)
    }
  })
}


async function hello () {
  // 判断是否有报错
  try{
    const res = await firstAsync()
    console.log(res)
  }catch(err){
    console.log("err")
    console.log(err)
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 第二种处理方法:.catch

  • 优点:代码优雅,适合对await函数进行异步错误处理
  • 缺点:需要对返回值再进行一次判断。
// 定义一个函数,返回promise对象
function firstAsync() {
  return new Promise((resolve,reject) => {
    const a = 0;
    if(a){
      resolve(1)
    }else{
      reject(2)
    }
  })
}


async function hello () {
  // 判断是否有报错
  const res = await firstAsync().catch(err =>{
    console.log("err")
    console.log(err)
  })
  if(res){
      //TODO
  }
}

hello();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

# 第三种处理方法,两个返回值

  • 优点:统一错误处理可以在定义的函数内执行,await调用只需要对返回值进行判断即可,不需要单独进行catch处理
  • 缺点:返回值是两个,不容易管理
const awaitWrap = () => {
  let promise = new Promise((resolve,reject) => {
    const a = 0;
    if(a){
      resolve(1)
    }else{
      reject(2)
    }
  })
  return promise
  .then(data => [data, null])
  .catch(err => {
    // 通用错误处理写这里 TODO
    return [null,err]
  })
}

async function he() {
  const [data, err] = await awaitWrap();
  if(data){
    //如果是resolve走这里
    console.log(data)
  }else{
    //如果是reject走这里
    console.log("error")
    console.log(err)
    //特殊错误处理写这里 TODO
  }
}

he();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
更新时间: 2021-09-15 12:03