js回调地狱及解决方案:promise,async

在Javascript中函数是第一类对象,可被存储在变量中,也能作为函数的参数传递

js是单线程语言,所有脚本同步执行,但是我们有时候需要等待某个时机才执行某些脚本也就是做异步操作,于是出现了如下代码:

我们成setTimeout函数中的参数为回调函数

当我们需要在2000ms后,再开启一个定时器,则会如下定义代码:

如果需要再timer end2输出后开启更多的定时器,则需要依次嵌套下去,如此变出现了一列回调小火箭,我们称之为回调地狱

这段代码虽然在功能上不存在什么问题,但是在代码可读性以及维护性方面惨不忍睹,对此es6提供了一些列异步编程解决方案。

1、promise

prmoise是一个对象,专门用于处理异步操作,该对象有三个状态:进行中、已完成、已失败,当前状态仅由异步操作的结果决定,不受任何其他操作控制,且一旦执行就无法取消

上图代码,resolve函数执行后,promise对象状态将会从“未完成”变为“成功”,reject则是变为“失败”,基于此我们可以使用then方法分别指定“成功”与“失败”状态的回调函数

如此可便可以通过链式调用的方式将执行逻辑串联起来,同时也将回调处理从上层代码中抽离

2、async

promise对象的链式串联方式虽然解决了回调函数的层层嵌套问题,但是then操作过多过长时还是会出现冗余臃肿的情况,此时可以使用async函数。

async函数是es7的语法,但是bable已经提供了相关的转译功能

function timeout(data){
            return new Promise((resolve, reject)=>{
                setTimeout(function(){
                    if(data){
                        resolve(data)
                    }else{
                        reject(data)
                    }
                },3000)
            })
        }
        class agent{
            async run(){
                console.log("agent run start")
                await timeout("agent")
                console.log("agent run end")
            }
        }
        let agentIns = new agentExtend();
        
        agentIns.run()

如上图所示,还是使用了前面的timeout函数,只不过在run方法上加了async标识,然后在调用异步promise函数时加上await关键字,console.log("agent run end")函数则会等待timeout函数执行resolve()操作后再执行,如果由多个异步操作,则在每个异步函数前加上await关键字即可达到暂缓执行的效果,直到异步Promise对象状态改变

最后说明一下,promise,async都是外同内异,看起来是同步执行的效果,本质上还是异步回调,只不过ECMAScript包装过的一个语法糖

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值