2012-10-27 11 views
7

次のコード例があります。最初の部分では非同期呼び出しが発生する可能性があります。私は非同期コールバック内に残りのコードを置くことはできません。なぜなら、条件がfalseのときに実行する必要があるからです。だからこれをどうやって?ノードで非同期関数を条件付きで呼び出す

if(condition) { 
    someAsyncRequest(function(error, result)) { 
     //do something then continue 
    } 
} 

//do this next whether condition is true or not 

私はコードを置くことは行くし、条件が偽である場合は、上記または他の呼び出しで非同期呼び出し内でその機能を呼び出すための方法かもしれない機能で後に来ていると仮定 - しかし、別の方法がありますそれは機能の中でそれを壊す必要はありませんか?あなたがそれを必要なとき

+0

非同期待つパッケージが役立つかもしれません(シンクスタイルで非同期コードを書くことができ、例外をサポートするなど)https://www.npmjs.com/package/asyncawait - このような構文も今後のNodeバージョンでネイティブにサポートされています(https:// githubを参照)。com/nodejs/promises/issues/4 –

答えて

3

だけ実行されるように、いくつかの他の関数を宣言:

var otherFunc = function() { 
    //do this next whether condition is true or not 
} 

if(condition) { 
    someAsyncRequest(function(error, result)) { 
     //do something then continue 

     otherFunc(); 
    } 
} else { 
    otherFunc(); 
} 
+3

これは私が今述べてきたものです。関数にコードをカプセル化しないようにする方法があるのだろうかと疑問に思っているのですか? – cyberwombat

+0

@Yashua、someAsyncRequestは非同期なので、 JavaScriptは本質的に*マルチ*スレッドではないので、非同期呼び出しが行われるまでは、プログラムの一部を単に「一時停止」することはできません。したがって、関数の中で後で実行し、適切な時刻に(つまり、すぐに、または非同期コードが実行されたときに)呼び出すために、コードの部分を保護する必要があります。 –

3

それを行うにはちょうど別の方法で、これは私がパターンを抽象化する方法です。同じことを扱うライブラリ(約束?)があるかもしれません。

function conditional(condition, conditional_fun, callback) { 
    if(condition) 
     return conditional_fun(callback); 
    return callback(); 
} 

そしてコードで、あなたは

conditional(something === undefined, 
      function(callback) { 
       fetch_that_something_async(function() { 
        callback(); 
       }); 
      }, 
      function() { 

         /// ... This is where your code would continue 


      }); 
0

を書くことができます私は、非同期呼び出しを扱うときに人生が超簡単になり素晴らしいcore-asyncライブラリを持っているclojurescriptを使用することをお勧めします。

(go 
    (when condition 
    (<! (someAsyncRequest))) 
    (otherCodeToHappenWhetherConditionIsTrueOrNot)) 

注体が非同期で実行させ、および非同期関数が返されますまでブロックします<!機能しますgoマクロ:あなたのケースでは

、あなたはこのような何かを書くでしょう。 <!関数がwhenの条件の中にあるため、条件が真である場合にのみブロックされます。

+0

@kleopatra私の答えを編集してください。私はこれが今より良いことを願っています。 – Asher

+0

ありがとうございます:-) – kleopatra

7

私がNodeで使ったライブラリは、しばしばAsync(https://github.com/caolan/async)です。最後に私はこれもブラウザのサポートを持っていることを確認したので、あなたの配布物でこれをnpm/concat/minifyできるはずです。これをサーバー側でのみ使用している場合は、若干改善されたAsyncのバージョンであるhttps://github.com/continuationlabs/insyncを検討してください。一部のブラウザサポートは削除されています。

条件付き非同期呼び出しを使用する際に私が使用する一般的なパターンの1つは、配列に配列を順番に挿入してasync.waterfallに渡すことです。

以下に例を示します。

var tasks = []; 

if (conditionOne) { 
    tasks.push(functionOne); 
} 

if (conditionTwo) { 
    tasks.push(functionTwo); 
} 

if (conditionThree) { 
    tasks.push(functionThree); 
} 

async.waterfall(tasks, function (err, result) { 
    // do something with the result. 
    // if any functions in the task throws an error, this function is 
    // immediately called with err == <that error> 
}); 

var functionOne = function(callback) { 
    // do something 
    // callback(null, some_result); 
}; 

var functionTwo = function(previousResult, callback) { 
    // do something with previous result if needed 
    // callback(null, previousResult, some_result); 
}; 

var functionThree = function(previousResult, callback) { 
    // do something with previous result if needed 
    // callback(null, some_result); 
}; 

もちろん、代わりに約束を使用することができます。どちらの場合でも、私は非同期または約束を使用してコールバックの入れ子を避けるのが好きです。

あなたは、ネストされたコールバックを使用しないことによって回避することができ、物事のいくつかのバグを巻き上げ、変数衝突され、「マーチング」コードを読みにくく右>>>>には、など

+1

FWIW、ここで扱う最初のアンチパターンの代わりにAsyncが使用されています: http://webapplog.com/seven-things-you-should-stop-doing-with-node-js / – zedd45

関連する問題