2017-03-28 26 views
0

私はリストを反復処理し、その後最初の関数の結果が見つかった場合にのみ2つの関数を呼び出すforループを実装しようとしています。javascript関数の呼び出しタイミング

問題は、2番目の関数(search.similar)の結果を取得するのに時間がかかることがあるということです。

以下のコードでは、(search.locate)からの適切な出力はすべて正しいものの、myListの最後の要素の結果のみが(search.similar)関数から格納されます。

ie。 all_results = [[cat_res1,mouse_res2],[dog_res1,mouse_res2],[mouse_res1,mouse_res2]]

正しい結果を正しい順序で追加するにはどうすればよいですか?

ie。 all_results = [[cat_res1,cat_res2],[dog_res1,dog_res2],[mouse_res1,mouse_res2]]

var search = require('./search'); 
var myList = ['cat','dog','mouse']; 
var all_results = []; 
for (i=0; i<myList.length; i++){ 
    /* locate function*/ 
    search.locate(myList[i], function (err, searchResult){ 
    if (err){ 
     console.log("Error"); 
     return; 
    } 

    if (!searchResult){ 
     console.log("Cannot find it"); 
     return; 
    } 

    /*similarity function*/ 
    /* seems to take longer*/ 
    search.similar(myList[i], function (err, similarResult){ 
     if (err){ 
     return; 
     } 

     if (!similarResult){ 
     return; 
     } 

     var res1 = searchResult.data; 
     var res2 = similarResult.data; 
     /* append results to array*/ 
     all_results.push([res1,res2]); 
    } 
    }); 
} 
+0

* search.locate *と* search.similar *によって返された値の何種類?メソッドは非同期ですか? – RobG

+0

'push'を使わずに、適切にスコープされたインデックスに保存するそれぞれのインデックスに割り当てます(http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example)変数。 – Bergi

+0

@RobG彼らが何らかのオブジェクトであると仮定しましょう。 – chattrat423

答えて

0

Javascriptが特定の機能の実行は必ずしも非同期は、おそらく誤解を招くようしかし、」JavaScriptを記述し、同期的に発生しないという点で、非同期考えることができます。それにはJavaScriptを同期および単一であると言うことは、より正確ですさまざまなコールバックメカニズムでスレッドされます。

目的を達成するためには、まだ最上位の配列で発注問題が発生する可能性がありますが、両方の引数を取る別の関数で.similar()呼び出しをラップする必要があります。トップ検索の「アイテム」をご参照が変更されます。

function searchNestedSimilar(item, topRes) { 
    search.similar(item, function (err, similarResult) { 

     if (err){ 
      return; 
     } 
     if (!topRes){ 
      return; 
     } 

     var res1 = topRes.data 
     var res2 = similarResult.data 

     // append results to array 
     all_results.push([res1,res2]) 

    } 
} 

function searchLocate(item) { 
    search.locate(item, function (err, searchResult) { 

    if (err){ 
     console.log("Error"); 
     return; 
    } 
    if (!searchResult){ 
     console.log("Cannot find it"); 
     return; 
    } 
    searchNestedSimilar(item, searchResults); 
} 

を私はモジュラーそれを維持するために呼び出しますが、「アイテム」は閉鎖しているので、あなたが本当にあなただけのをラップするsearchLocate()機能を必要とする両方のカプセル化反復中にアイテム参照を取得します。

+0

はい、このコードには問題が解決するよう依頼された発注の問題があります。 – Bergi

+0

"*トップ検索*の参考情報"とは何を意味するのかよく分かりませんか? – Bergi

+0

"* Javascriptは非同期です*" - 一般的ではありません。 – RobG

0

これはPromises(Bluebird JSの例、http://bluebirdjs.com/docs/getting-started.htmlなど)の場合や、 async.map()で行うことができます。

このページでは、このことについてもよく話しています。 http://promise-nuggets.github.io/articles/14-map-in-parallel.html

約束について議論する多くのスタックオーバーフローがあります。例えば、Understanding JS Promises

約束でこれをどのように書くかの大まかな例:

var search = require('./search'); 
var myList = ['cat','dog','mouse'] 
var all_results = [] 
var Promise = require('bluebird'); 
var locate = Promise.promisify(search.locate); 
var similar = Promise.promisify(search.similar); 

for (i = 0; i < myList.length; i++){ 
    // locate function 
    locate(myList[i], function (err, searchResult) { 
     if (err) { 
      console.log("Error"); 
      return; 
     } 
     if (!searchResult){ 
      console.log("Cannot find it"); 
      return; 
     } 
    }).then(function(result) { 
     //similarity function 
     similar(myList[i], function (err, similarResult) { 
      if (err){ 
       return; 
      } 
      if (!similarResult){ 
       return; 
      } 

      var res1 = searchResult.data 
      var res2 = similarResult.data 

      // append results to array 
      all_results.push([res1,res2]) 
     }).finally(function() { 
      // NOP 
     }); 
    }); 
} 
関連する問題