これがあなたがすべきだと私が考える方法です。
チェーンを分割する
どちらの関数もamazingDataを使用するため、専用の関数に含めるのは理にかなっています。私は通常、一部のデータを再利用するたびにこれを行うため、関数argとして常に存在します。
あなたの例はいくつかのコードを実行しているので、それはすべて関数内で宣言されていると思います。これをtoto()と呼びます。次に、afterSomething()とafterSomethingElse()の両方を実行する別の関数があります。
function toto() {
return somethingAsync()
.then( tata );
}
また、通常はPromisesを使用する方法であるため、returnステートメントを追加したことに気付くでしょう。必要に応じてチェーンを継続できるように、常にPromiseを返します。ここで、somethingAsync()はamazingDataを生成し、新しい関数内のどこでも利用できるようになります。
この新しい関数が通常どのように見えるかは、processAsync()も非同期ですか?
processAsyncは非同期ではありません
processAsync()が非同期でない場合、物事を過度に複雑にする理由はありません。いくつかの古い良いシーケンシャルコードがそれを作ります。
function tata( amazingData ) {
var processed = afterSomething( amazingData );
return afterSomethingElse( amazingData, processed );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
afterSomethingElse()が何か非同期を行っているかどうかは問題ではないことに注意してください。もしそうなら、約束が返され、チェーンは継続することができます。そうでない場合は、結果値が返されます。ただし、関数はthen()から呼び出されるため、値はとにかく(少なくとも生のJavascriptでは)promiseにラップされます。
processAsync非同期
場合processAsync()は非同期で、コードが若干異なって見えます。ここでは、afterSomething()とafterSomethingElse()が他の場所で再利用されないことを考慮します。
function tata( amazingData ) {
return afterSomething()
.then( afterSomethingElse );
function afterSomething( /* no args */ ) {
return processAsync( amazingData );
}
function afterSomethingElse( processedData ) {
}
}
afterSomethingElse()については前と同じです。非同期でもそうでなくてもかまいません。promiseが返されるか、解決されたpromiseに値がラップされます。
あなたのコーディングスタイルは私が以前行っていたものに非常に近いので、2年経っても答えました。私はどこにでも匿名関数を持つことの大ファンではありません。読みづらいと思います。たとえそれがコミュニティでかなり一般的であるとしても。これは、callback-hellをpromise-purgatoryに置き換えたときのことです。
私はまた、内の関数の名前を維持したい、その後短いです。とにかく、それらはローカルでのみ定義されます。そして、ほとんどの場合、他の場所で定義されている別の関数(再利用可能)を呼び出して、ジョブを実行します。パラメータが1つしかない関数に対してもこれを行うので、関数シグネチャにパラメータを追加/削除するときに関数を出し入れする必要はありません。
食事の例
次に例を示します。
function goingThroughTheEatingProcess(plenty, of, args, to, match, real, life) {
return iAmAsync()
.then(chew)
.then(swallow);
function chew(result) {
return carefullyChewThis(plenty, of, args, "water", "piece of tooth", result);
}
function swallow(wine) {
return nowIsTimeToSwallow(match, real, life, wine);
}
}
function iAmAsync() {
return Promise.resolve("mooooore");
}
function carefullyChewThis(plenty, of, args, and, some, more) {
return true;
}
function nowIsTimeToSwallow(match, real, life, bobool) {
}
Promise.resolve()に集中しすぎないでください。これは、解決されたプロミスを作成するための簡単な方法です。これによって私が達成しようとしているのは、実行しているすべてのコードを1つの場所(thensのすぐ下)に配置することです。よりわかりやすい名前を持つ他のすべての関数は再利用可能です。
この手法の欠点は、多くの関数を定義していることです。しかし、あちこちで匿名関数を持つことを避けるために、私が恐れているのは必要な苦痛です。そしてとにかくリスクは何ですか:スタックオーバーフロー?(冗談で!)
他の回答で定義されている配列またはオブジェクトを使用することもできます。これはある意味でKevinReidによって提案された答えです。
bind()またはPromise.all()を使用することもできます。それでもコードを分割する必要があることに注意してください。
バインドを使用する
関数を再利用可能に保ちたいが、その内部にあるものを非常に短く保つ必要がない場合は、bind()を使用できます。
function tata( amazingData ) {
return afterSomething( amazingData )
.then( afterSomethingElse.bind(null, amazingData) );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( amazingData, processedData ) {
}
簡単にするために、bind()は、呼び出されたときに、引数のリスト(最初のリストを除く)を関数の前に追加します。
Promise.allを使用する
あなたの投稿では、spread()の使用について言及しました。私はあなたが使用しているフレームワークを使用したことはありませんが、これがあなたがそれを使用できるはずの方法です。
Promise.all()がすべての問題の解決策であると信じている人もいるので、言及する価値があると思います。
function tata( amazingData ) {
return Promise.all( [ amazingData, afterSomething( amazingData ) ] )
.then( afterSomethingElse );
}
function afterSomething( amazingData ) {
return processAsync( amazingData );
}
function afterSomethingElse( args ) {
var amazingData = args[0];
var processedData = args[1];
}
Promise.all()にデータを渡すことができます(配列の存在に注意してください)が、promiseが失敗しないことを確認してください。失敗しないと、処理が停止します。
そして、args引数から新しい変数を定義する代わりに、then()の代わりにspread()を使用して、あらゆる種類のすばらしい作業を行うことができるはずです。