async await函数性能与Promise并发

有时候我们需要等待两个异步结果来执行接下来的操作,这个时候,如果使用async/await写出近似于同步的流程,可能会有性能问题

我们看一下这个例子的运行时间

function foo() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(10)
        }, 1000)
    })
}
function bar() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(20)
        }, 1500)
    })
}

async function test() {
    let start = new Date().getTime()
    let val1 = await foo()
    let val2 = await bar()
    
    let val  = val1 + val2
    let end  = new Date().getTime()
    let time = end - start
    console.log(val)
    console.log(time)
    
}
// 结果
// 30  val的结果
// 2505 test()运行时间
复制代码

我们换一种写法,再来看看运行时间

function foo() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(10)
        }, 1000)
    })
}
function bar() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(20)
        }, 1500)
    })
}

async function test() {
    let start = new Date().getTime()
    let p1 = foo()
    let p2 = bar()
    let val1 = await p1
    let val2 = await p2
    
    let val  = val1 + val2
    let end  = new Date().getTime()
    let time = end - start
    console.log(val)
    console.log(time)
    
}
// 结果
// 30  val的结果
// 1501 test()运行时间
复制代码

换一种写法,test()的运行时间少了一秒钟是不是?

这是因为第一种写法,必须等foo()运行结束才能运行bar(),所以所用的时间是两个异步Promise等待时间的和;

而第二种写法中,因为提前定义p1和p2,提前运行了这两个Promise,程序运行到await p1的时候两个Promsie都已经开始运行,也就是它们是并行的;

这样test()的运行时间主要就取决于用时更长的那个Promise而不是两者的相加。

或者我们也可以使用Promise.all()来实现

function foo() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(10)
        }, 1000)
    })
}
function bar() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve(20)
        }, 1500)
    })
}

async function test() {
    let start = new Date().getTime()
    let vals = await Promise.all([foo(), bar()])
    
    let val  = vals[0] + vals[1]
    let end  = new Date().getTime()
    let time = end - start
    console.log(val)
    console.log(time)
    
}
// 结果
// 30  val的结果
// 1501 test()运行时间
复制代码

这种写法已经相当靠谱,但是,我们还是有优化的空间;

async/await函数不应该关心异步Promise的具体实现细节,await应该只关心最终得到的结果,这样为更加复杂的异步操作提供更加清晰的过程控制逻辑。

function getVal() {
    return Promise.all([foo, bar])
}

async function test() {
    let vals = await getVal()
    
    let val = vals[0] + vals[1]
    console.log(val)
}
复制代码

应该有意识的把这种逻辑从async/await中抽离出来,避免低层次的逻辑影响了高层次的逻辑;这也应该是所有的高度抽象化代码中必要的一个环节,不同逻辑层次的代码混杂在一起最终会像回调地狱一样让自己和读自己代码的人陷入混乱。

转载于:https://juejin.im/post/5c09dcb5e51d451dc47e279d

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值