promise和async await

113 阅读4分钟

promise概念

Promise是异步编程的一种解决方案,用于实现异步编程。

Callback和Promise同异

共同点:都能解决异步问题。

区别:

  • Callback是递归深度,Promise是链式宽度
  • Promise是ES6标准提出异步编程解决方案。
  • 答promise的优点。

优缺点/为什么要用promise

优点:

  • 改变异步编码风格,避免回调函数层层嵌套,解决回调地狱,改成链式调用。代码可读性明显增强。

    终极解决方案是promise链式调用改为async和await。用await promise对象,接收异步操作返回的数据。

  • 合并多个任务的错误处理。以前是每个任务执行结束后分别处理成功或失败两种可能性。

  • 指定回调函数的方式更加灵活

    之前是必须在启动异步任务前指定回调函数,现在异步任务结束前后都可给promise对象绑定then回调函数,也可绑定多个回调函数。

缺点:

  • 一旦新建Promise就会立即执行,无法中途暂停/取消程序

    中断promise链条:有且只有一个方式:在回调函数中返回一个pending状态的promise对象,如return new Promise(() => {})

    async函数可以中途暂停/取消程序,使用await/return可以暂停/取消。

  • 处于pending状态时,是不能知道目前进展到哪个阶段的,比如无法判断是刚开始还是即将结束。

  • 如果不设置回调函数,Promise内部抛出的错误不会反映到外部。所以需要设置reject、catch等回调函数。

Async/Await

async/await是异步编程的终极解决方案。

  • sync意思是同步,async意思是异步。
  • //不阻塞主线程,使用同步代码实现异步操作??

Async/Await和Promise区别

为什么有了Promise还要有Async/Await?

  • 一旦新建Promise就会立即执行,无法中途暂停/取消程序。async函数可以使用await/return可以暂停/取消。

  • Promise有大量的then⽅法、catch方法指定回调函数,语义化不明显。

    而Async/Await可通过await拿到成功对象的值,try catch捕获异常。

  • Async/Await更简洁,不用new Promise匿名参数生成promise对象,async总会隐式返回Promise对象。

  • 捕获异常中同步任务与异步任务的不同。而且Async/Await可以定位到出错的await处,因为冒泡catch方法无法判断具体哪个promise对象出错。

  • 条件语句。await判断比then中判断条件语句更简便。

  • await后代码,看做是(resolve, reject) => {}中代码,同步代码立即执行
  • await下一条语句,看作是then(res => {})中代码,前面有结果才会执行微任务。

Async/Await原理

async/await使⽤了Generator + Promise两种技术,即协程和微任务技术。

  • Async/Await告别了Generator生成器 + 执行器/CO模块,可自动执行Generator函数更加简洁。await代替yield。

async语法

async是⼀个通过异步执行隐式返回Promise对象的函数。

  • 返回值是Promise对象。对象的状态和值取决于函数返回值、抛出异常/错误。

    • 若接收函数没有返回值,返回promise对象的状态为成功,值为undefined。因为内部实现了Promise.resolve(value)。
    • 若接收函数的返回值是非promise对象的数据,返回promise对象的状态为成功,值为数据值。因为内部实现了Promise.resolve(value)。
    • 若接收函数的返回值是promise对象的数据,则正常返回该返回值。对象状态先是pending,再改变状态。
    • 若接收函数抛出异常/错误如throw "error",则返回promise对象的状态是失败,值是throw后的值。
  • async函数可单独使用,返回Promise对象。

  • 当async和await一起使用时,async写在await所在的最近函数定义的左侧。

await语法

  • await意思是async wait,等待异步方法执行。

  • await命令后面可以是原始类型的值、Promise对象。await 成功promise对象,可直接取到成功promise对象的值。

  • await必须写在async函数中,把await限制在async函数中使用,单独使用会报错。在返回promise对象的表达式左侧写await。

  • 每次遇到await后续代码停止执行,所以第二个请求在第一个请求成功之后才发送。如果不想要这种效果可使用Promise.all()。

    • async/await执行时间为每个promise请求所用的时间,相加之和。
    • Promise.all()执行时间为最慢的那个promise请求所用的时间,返回值为每个请求成功值组成的数组。

捕获异常

try{} catch(){}:如果try中抛出异常,则马上被catch捕获,try中后续内容不会再执行。