有时候咱们须要等待两个异步结果来执行接下来的操做,这个时候,若是使用async/await写出近似于同步的流程,可能会有性能问题bash
咱们看一下这个例子的运行时间异步
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()运行时间
复制代码
咱们换一种写法,再来看看运行时间async
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而不是二者的相加。ui
或者咱们也可使用Promise.all()来实现spa
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()运行时间
复制代码
这种写法已经至关靠谱,可是,咱们仍是有优化的空间;code
async/await函数不该该关心异步Promise的具体实现细节,await应该只关心最终获得的结果,这样为更加复杂的异步操做提供更加清晰的过程控制逻辑。get
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中抽离出来,避免低层次的逻辑影响了高层次的逻辑;这也应该是全部的高度抽象化代码中必要的一个环节,不一样逻辑层次的代码混杂在一块儿最终会像回调地狱同样让本身和读本身代码的人陷入混乱。