async await関数のパフォーマンスとPromiseの同時性

6053 ワード

次の操作を実行するために2つの非同期結果を待つ必要がある場合があります.この場合、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()の運行時間が1秒少なくなったのではないでしょうか.
これは、foo()の実行が終了するまでbar()を実行できないため、2つの非同期Promise待ち時間の和が用いられるためである.
第2の書き方では、p 1とp 2を事前に定義したため、この2つのPromiseを事前に実行し、プログラムがawait p 1に実行されると、2つの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