细数promise与async/await的使用及区别说明

 更新时间:2022年07月28日 15:09:59   作者:尼克_张  
这篇文章主要介绍了细数promise与async/await的使用及区别说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

简单的一张图可以直观的表现出 callback、Promise 和 async/await 在使用时的主要区别。

在这里插入图片描述

一、callback,Promise,async&await三者的区别?

1.callback 经过深层次的嵌套,会产生回调地狱,需手动检查err参数。

2.promise 通过链式调用,直接在 then 中返回一个 promise 来进行成功之后的回调函数,用 catch 来做错误处理。

3.async/await 则直接将其变成了同步的写法,既可以用.catch又可以用try-catch捕捉,简洁,可读性强,写法更加优雅 。

//try...catch
const fn = () => {
    return new Promise((resolve, reject) => {
        reject('你错啦~~')
    })
}
const asyncFn = async () => {
    try {
        let result1 = await fn()
    } catch (error) {
        console.log('try...catch:' + error)
    }
}
asyncFn()   //try...catch:你错啦~~
//catch
const asyncFn1 = async () => {
    const res = await fn().catch(err => console.log('catch:' + err))
}
asyncFn1()   //catch:你错啦~~

注意: try…catch可以捕获promise异常吗?

不能,try…catch 主要用于捕获异常,这里的异常,是指同步函数的异常。

二、Promise

1.Promise的特点

1.无法取消Promise,一旦新建它就会立即执行,无法中途取消。

2.如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。

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

2.Promise的用法

1.Promise的三种状态

  • pending: 进行中
  • fulfilled: 成功
  • rejected: 失败

Promise 构造函数有两个参数 resolve和 reject,分别对应成功和失败后的回调函数

2.Promise原型上的方法

  • then: 成功时的回调
  • catch: 失败时的回调
  • finally: 执行完毕后无论其结果怎样都做一些处理

3.Promise的静态方法

  • Promise.all() 有一个Promise对象失败则全部失败,输出第一个失败的原因
  • Promise.allSettled() 不关心Promise对象的成功或者失败,只关心结果
  • Promise.any() 返回第一个成功的Promise对象
  • Promise.race() 返回执行最快的那个Promise对象,无论它是成功还是失败
  • Promise.resolve() 返回一个状态为成功的Promise对象
  • Promise.reject() 返回一个状态为失败的Promise对象
let p1 = new Promise((resolve, reject) => {
    setTimeout(resolve, 400, 'one');
});
let p2 = Promise.reject("two");
let p3 = new Promise((resolve, reject) => {
    setTimeout(resolve, 1000, 'three');
});
let p4 = Promise.resolve("four");
let p5 = new Promise((resolve, reject) => {
    // reject('reject');
    setTimeout(resolve, 500, 'five');
})
Promise.all([p1,p2,p3,p4,p5]).then(values => {
    console.log(values,"all"); 
}).catch((err) => {
    console.log(err,"allBad"); 
})

Promise.allSettled([p1,p2,p3,p4,p5]).then(values => {
    console.log(values,"allSettled"); 
}).catch((err) => {
    console.log(err,"allSettledBad"); 
})

Promise.any([p1,p2,p3,p4,p5]).then(values => {
    console.log(values,"any"); 
}).catch((err) => {
    console.log(err,"anyBad"); 
})

Promise.race([p1,p2,p3,p4,p5]).then(values => {
    console.log(values,"race"); 
}).catch((err) => {
    console.log(err,"raceBad"); 
})

3.Promise的运用(请结合js事件循环)

1.红灯3秒亮一次,绿灯1秒亮一次,黄灯2秒亮一次;如何使用Promise让三个灯不断交替重复亮灯?

function mylight(value,time){
    return new Promise((resolve,reject) => {
        setTimeout((params) => {
            console.log(value);
            resolve()
        },time)
    })
}

let step =()=>{
    Promise.resolve()
    .then(() => {
    //此处的return是为了执行后面的.then
        return mylight('red',3000)
    })
    .then((res) => {
        return mylight('green',1000)
    })
    .then((res) => {
        return mylight('yellow',2000)
    })
    .then(res=>{
      // 递归执行
       step()
    })
}
step()

扩展:使用reduce实现以上代码?reduce用法

// 用reduce相当于往后面叠加.then,跟上面的重复亮灯代码一样
const arr = [
    {
        color:"red",
        time:3000,
    },
    {
        color:'green',
        time:1000,
    },
    {
        color:'yellow',
        time:2000
    }
]
function fn(arr) {
    arr.reduce((pre, cur,index) => {
        return pre.then(() => {
            return new Promise(resolve => {
                setTimeout(() => {
                    resolve(console.log(cur.color))
                }, cur.time)
            })
        })
    }, Promise.resolve()).then((params) => {
       fn(arr)
    })
    // 以上代码简写为:
    // arr.reduce((pre, cur) => pre.then(() => new Promise(r => setTimeout(() => r(console.log(cur.color)), cur.time))), Promise.resolve()).then((params) => fn(arr))
}
fn(arr)

三、async与await

1.async与await介绍

async await 需成对出现,async await原理是生成器, 

async函数就是将 Generator 函数的星号(*)替换成async,将yield替换成await,参照 Generator 封装的一套异步处理方案,可以理解为 Generator 的语法糖, 

而 Generator 又依赖于迭代器Iterator, 

而 Iterator 的思想又来源于单向链表。

2.async和await的用法

1 async和await把异步改为同步,得到最新的state的值

使用Promise来封装setState(异步编程)

changeCount = (state)=>{
    return new Promise((resolve,reject)=>{
      setTimeout(()=>{
          this.setState(state)
        //resolve包裹成功时的结果
          resolve(this.state.count)
     },100)
   })
 },
pushRouter = async() => {
  //  await this.setState({
  //     count:this.state.count+1
  //   })
   const result = await this.changeCount({
   		count:this.state.count + 1
   })
}

2 async,await结合try,catch使用捕获异常

async componentDidMount() {
   const { dispatch } = this.props
   try {
         const response = await dispatch({
              type: "netValueQuery/queryListData",
              payload: {}
         })
         if (response.httpStatus !== 200) {
             throw new Error(response.msg);
         }
         const json = await response.json();
         this.setState({ data: json });
       } catch (error) {
         console.log(error);
   }
}

3 多个请求,后面的请求里需使用前面请求里返回的值

getSign(result){
    return this.$post(`/share/saveRecord`)
},
getTask() {
    const actid = this.$route.query.id;
    return this.$get(`/lottery/powerTask/${actid}`);
},
async getReady(){
    const task = await this.getTask()
    this.result = task.data.find(item => item.name.includes("分享"))
    const str = await this.getSign(this.result)
},

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • JavaScript实现文件的拖拽上传功能

    JavaScript实现文件的拖拽上传功能

    文件上传,可以说是我们在项目中最常用的功能之一,文件上传一般有两种形式:点击上传和拖拽上传,而上传的内容,又大体包括:文件和文件夹,本文给大家介绍了JavaScript实现文件的拖拽上传功能的方法,需要的朋友可以参考下
    2024-02-02
  • ES2015 Symbol 一种绝不重复的值

    ES2015 Symbol 一种绝不重复的值

    这篇文章主要介绍了Symbol是ES2015新增的一种值类型数据,表示一种绝不重复的值,需要的朋友可以参考下
    2016-12-12
  • 浅谈JS原型对象和原型链

    浅谈JS原型对象和原型链

    这篇文章主要为大家详细介绍了JS原型对象和原型链,感兴趣的小伙伴们可以参考一下
    2016-03-03
  • vue 组件销毁并重置的实现

    vue 组件销毁并重置的实现

    这篇文章主要介绍了vue 组件销毁并重置的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • 移动端基础事件总结与应用

    移动端基础事件总结与应用

    本文主要介绍了移动端基础事件总结与应用,具有一定的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • JS中的算法与数据结构之链表(Linked-list)实例详解

    JS中的算法与数据结构之链表(Linked-list)实例详解

    这篇文章主要介绍了JS中的算法与数据结构之链表(Linked-list),结合实例形式详细分析了javascript中链表的概念、原理、定义及常用操作技巧,需要的朋友可以参考下
    2019-08-08
  • ajax请求前端跨域问题原因及解决方案

    ajax请求前端跨域问题原因及解决方案

    这篇文章主要为大家介绍了ajax请求前端跨域问题原因及解决方案,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-10-10
  • Axios+Spring Boot实现文件上传和下载

    Axios+Spring Boot实现文件上传和下载

    这篇文章主要为大家详细介绍了Axios+Spring Boot实现文件上传和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • js+html5实现手机九宫格密码解锁功能

    js+html5实现手机九宫格密码解锁功能

    这篇文章主要为大家详细介绍了js+html5实现手机九宫格密码解锁功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • javascript常见数据验证插件大全

    javascript常见数据验证插件大全

    这篇文章主要介绍了javascript常见数据验证插件大全,需要的朋友可以参考下
    2015-08-08

最新评论