promise和async/await的区别

385 阅读4分钟

一、Promise基础认识

了解:

Promise是ES6中的一个内置对象,实际是一个构造函数

Promise是一种解决异步编程的方案,相比回调函数和事件更合理和更 强大

promise 是一个对象,从它可以获取异步操作的消息

特点:
  • 三种状态:pending(进行中)、resolved(已完成)、rejected(已失败)。只有异步操作的结果可以决定当前是哪一种状态,任何其他操作都不能改变这个状态。

  • 两种状态的转化:其一,从pending(进行中)到resolved(已完成)。其二,从pending(进行中)到rejected(已失败)。只有这两种形式的转变。

  • Promise构造函数的原型对象上,有then()catch()等方法,then()第一个参数接收resolved()传来的数据,catch()第一个参数接收rejected()传来的数据

缺点:
  • 无法取消 Promise,一旦新建它就会立即执行,无法中途取消

  • 如果不设置回调函数,Promise 内部抛出的错误,不会反映到外部

  • 当处于 pending(等待)状态时,无法得知目前进展到哪一个阶段, 是刚刚开始还是即将完成

作用:
  • 通常用来解决异步调用问题

  • 解决多层回调嵌套的方案

  • 提高代码可读性、更便于维护

使用:

手写promise

// 1. 创建一个新的Promise对象
const p = new Promise((resolve, reject) => { 
    // 2. 执行异步操作任务
    setTimeout(() => {
        const time = Date.now() 
        // 如果当前时间是偶数就代表成功,否则代表失败
        // 3.1 如果成功了,调用resolve(value)
        if (time % 2 === 0) {
            resolve('成功的数据,value = ' + time)
        } else {
            // 3.2 如果失败了,调用reject(reason)
            reject('失败的数据,reason = ' + time)
        }
    }, 1000);
})

p.then(value => {
    // 接受得到成功的value数据,专业术语:onResolved
    console.log('成功的回调', value)
}, reason => {
    // 接受得到失败的reason数据,专业术语:onRejected
    console.log('失败的回调', reason)
})

二、async await

  • async/await是ES8新特性

  • async/await是写异步代码的新方式,以前的方法有回调函数和Promise

  • async/await是基于Promise实现的,它不能用于普通的回调函数

  • async/await与Promise一样,是非阻塞的

  • async/await使得异步代码看起来像同步代码

async function用来定义一个返回 AsyncFunction 对象的异步函数。

异步函数是指通过事件循环异步执行的函数,它会通过一个隐式的Promise 返回其结果。

await操作符用于等待一个 Promise 对象。它只能在异步函数 async function 中使用。


三、promise和async/await的异同

相同:

  1. 两者都是处理异步请求的方式

  2. async/await是基于promise实现的,不能用于普通函数,和promise一样都是非阻塞的

区别:

  1. 提案版本: Promise是ES6的新特性,async/await是ES7中的提案

  2. 页面简洁: async/await更简洁干净,不需要用许多then();不需要写匿名函数处理Promiseresolve()值;也不需要定义多余的data变量;还避免了嵌套代码。

  3. 异常处理: promise是返回的对象要用.then().catch()去处理数据和捕获异常,而且书写方式是链式的,容易造成代码多层堆叠难以维护;async/await则是通过 try{}.catch{}进行捕获直接抛出异常

  4. 执行顺序: async/await最大的有点是使代码看起来像同步一样,一旦遇到 await就立即返回结果然后再执行后面的操作;用 promise.then()的方式返回,就可能在请求还没返回时就先执行了外面的操作

  5. 错误调试: async/awaittry{}.catch{}可以同时处理同步和异步错误。如果 Promise 连续调用,对于错误的处理是很麻烦的。你无法知道错误出在哪里。

  • 不能在返回表达式的箭头函数中设置断点,如果你在.then代码块中设置断点,使用Step Over快捷键,调试器不会跳到下一个.then,因为它只会跳过异步代码。

  • 使用await/async时,你不再需要那么多箭头函数,这样你就可以像调试同步代码一样跳过await语句。


内容参考: www.jianshu.com/p/0431e209d…