2017-09-18 5 views
1

最近私はjavascriptの約束を発見しました。広告されたメリットは、チェーン句とチェーン句によってクリーンなネストです。1つの約束の完了、次の開始前に長いリスト

私のコードは期待通りに機能しますが、ネストはコールバックを使用したときと同じくらい醜いものになります。このネストをすべて削除するには、チェーンの使用方法がありますか?タスクn + 1のタスクが開始する前に、タスクnを完了する必要があります。

非常に単純な固定例えば

'use strict'; 

function P1() { 

    return new Promise((resolve) => { 
     console.log("starting 1") 

     setTimeout(() => { 
      console.log("done 1") 
      resolve(); 
     }, 100) 
    }) 
} 

function P2() { 

    return new Promise((resolve) => { 
     console.log("must start 2 only after 1 is done") 

     setTimeout(() => { 
      console.log("done 2") 
      resolve(); 
     }, 50) 
    }) 
} 

function P3() { 

    return new Promise((resolve) => { 
     console.log("must start 3 only after 3 is done") 

     setTimeout(() => { 
      console.log("done 3") 
      resolve(); 
     }, 10) 
    }) 
} 

console.log("this works, but if list was long, nesting would be terribly deep"); 
// start 1, done 1, start 2, done 2, start 3, done 3. 
P1().then(() => { 
    P2().then(() => { 
     P3() 
    }) 
}) 

Iは

P1().then(() => { 
    return P2() 
}).then(() => { 
    return P3() 
}).catch(() => { console.log("yikes something failed")}) 

実際のコードを順次処理するものの配列を受け取りを行っているべきフィードバックに基づきます。 上記の推奨フォーマットは、一連のステップがコードとして指定されている場合にのみ適しています。 promiseチェーンを明示的に構築するコードではなく、Promise.do_these_sequentialyのようなものがあるようです。次のように:

'use strict'; 


function driver(single_command) { 
    console.log("executing " + single_command); 

    // various amounts of time to complete command 
    return new Promise((resolve) => { 
     setTimeout(() => { 
      console.log("completed " + single_command); 
      resolve() 
     }, Math.random()*1000) 
    }) 
} 

function execute_series_of_commands_sequentialy(commands) { 
    var P = driver(commands.shift()); 

    if (commands.length > 0) { 
     return P.then(() => { return execute_series_of_commands_sequentialy(commands) }) 
    } else { 
     return P 
    } 
} 

execute_series_of_commands_sequentialy([1, 2, 3, 4, 5, 6, 7, 8, 9]).then(() => { 
    console.log("test all done") 
}) 

答えて

1

約束がどのように機能するか誤解しています。戻り値とPromiseインスタンスを連鎖させてチェーンに沿ってさらに渡すことができます。

P1() 
.then(() => P2()) 
.then(() => P3()) 

ネストする必要はありません。

0

約束を書くのが非常に簡単になるasync/awaitを見てください。

JavaScript’s Async/Await Blows Promises Away

基本的には、同期コードのような非同期機能を書面で構成されています

async function P(number) { 
 
    return new Promise((resolve) => { 
 
     console.log("starting "+number) 
 

 
     setTimeout(() => { 
 
      console.log("done "+number) 
 
      resolve(); 
 
     }, 800) 
 
    }) 
 
} 
 

 
/* Or the ES6 version : 
 
    const P = async (number) => new Promise((resolve) => { ... }) 
 
*/ 
 

 
async function run(){ 
 
    await P(1) 
 
    await P(2) 
 
    await P(3) 
 
    
 
    console.log("All done!") 
 
} 
 

 
run()

1

は個人的に私はこのフォーマットが見て、どのように好きなことは、私が使用するものです

foo(){ 
    P1().then(()=>{ 
    return P2(); 
    }).then(()=>{ 
    return P3(); 
    }).catch((err)=>{ 
    //handle errors 
    }); 
} 
関連する問題