浅谈promise和async await区别

280 阅读3分钟

Promise

Promise是异步编程的一种解决方案,比传统的异步解决方案(回调函数)更强大,它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise对象。

基本用法

ES6规定,Promise对象是一个构造函数,用来生成Promise实例。基本用法如下:

const p = new Promise((resolve, reject) => {

    console.log('执行promise')

    setTimeout(() => {
        resolve('Hello Promise')
    }, 2000)
})

p.then((res) => {
    console.log('res=========', res)
})

浏览器打印输入如下:

image.png

本文重点讲述Promise和Async的区别,不展开讲Promise,有关Promise详细教程请参考:阮一峰ES6教程

Async await

ES2017标准引入了async函数,使得异步操作变的更加方便。async函数是什么?一句话,async函数是Generator函数的语法糖。要想理解async函数,就要先理解Generator函数。这里简单描述下Generator函数,不展开讲。

Generator函数

Generator函数是ES6提供的一种异步编程解决方案,语法行为与传统函数完全不同。下面是一个简单的generator函数

function* gen1() {
    yield "hello"
    yield "generator"
    return "end"
}

const res = gen1()

console.log('==========', res.next())
console.log('==========', res.next())
console.log('==========', res.next())

输出如下:

image.png

调用generator函数,返回一个遍历器对象,代表generator函数的内部指针。每次调用遍历器对象的next()方法,会返回一个有value和done属性的对象。value属性表示当前的内部状态的值,是yield表达式后面的值。done表示遍历是否结束。有关generator函数讲解请看文档

async

前面说到,async函数是generator函数的语法糖

// generator函数
function* gen1() {
    yield "hello"
    yield "generator"
    return "end"
}

const res1 = gen1()
console.log('=====', res1.next())
console.log('=====', res1.next())
console.log('=====', res1.next())

// async函数 
async function async1() {
    const aaa = await "hello"
    const bbb = await "async"
    console.log('aaa=======', aaa)
    console.log('bbb=======', bbb)
}

async1()

输出如下:

image.png

await后一般跟异步操作,比如调用接口。上一个await执行完毕后下一个才会开始执行,因此可以像写同步代码一样写异步操作。

async函数对generator函数的改进体现在以下几点:

  1. generator函数执行必须要执行器,因此才有了co模块。而async函数自带执行器,执行和普通函数一样。
  2. 更好的语义。async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。
  3. co模块约定,yield后面只能跟Thunk函数或者Promise对象。而await函数后面可以跟Promise对象和原始类型的值。
  4. async函数的返回值是Promise对象。可以使用then方法继续操作。
  5. yield没有返回值,await有返回值。

总结

promise和async await比较:

相同点:

  1. 都是异步编程解决方案
  2. async await是基于promise实现的,await只能在async函数中使用。

不同点:

  1. async await用同步的写法,可读性更强。
  2. async await可以使用try catch处理同步和异步错误。promise则不能使用try catch来统一处理异常。
  3. promise如果有多个then方法,异常捕捉比较麻烦。