2017-01-11 7 views
0

私はノードを使い慣れていませんし、ランダムな練習をしています。コールバックと非同期処理は私にとって初めてのことです。私はこの仕事をどのように達成できるのかを説明する助けに感謝します。コールバックが結果を返す前に関数が完了しました

私がしようとしているのは、Excelスプレッドシートから取得した行に基づいてオブジェクトを作成し、それをテーブルに追加/更新して個別に処理することです。

私が経験している問題は、ノードの初心者に共通して見られることは、同期処理の仕方を理解できていないことです。

デフォルトでは非同期で実行されるのはなぜですか?確かに、別のアクションが実行される前に何か起こってほしいと思っているのでしょうか?

これに正しく近づいていない可能性がありますか? このシナリオでは、Excelのデータセットから行を取得しています。データセットをループする際に、各行のオブジェクトを作成します。その一部は、別の関数(getAreaId)をコールバックしてarea_idを取得します。 areaCodeが渡されます。私のコンソールログでは、myOrganisationオブジェクトは常に定義されていないareaCodeを表示します。

私のコールバック関数内にconsole.logが表示されたら、正しい値が表示されます。コールバックから返された値をローカルオブジェクトに代入する最良の方法は何ですか?

私は読んだ私は非同期のようなミドルウェアを追加する必要があります。これがノードでの私の最初の試みなので、私は必要がなければ、ライブラリを追加したり、それ以上のことを複雑にしたりしたくないです。

function importData(){ 
    var myDataSet = getExcelData(); 
    var x = getOrganisationCode(function(existingOrgCode){ 

     for (j=0; j<myDataSet.length; j++){ 

      function organisationObj(orgCode, orgName, address1, areaCode){ 
       this.orgCode = orgCode; 
       this.orgName = orgName; 
       this.address1 = address1; 
       //this.areaId = getAreaId(areaCode, function(area_id){ return area_id}); 
       getAreaId(areaCode, function(area_id){ this.areaId = area_id}); 
      } 

      myOrganisation = new organisationObj(myDataSet[j]['OrgCode'], myDataSet[j]['OrgName'], myDataSet[j]['orgName'], myDataSet[j]['areaCode']); 

      console.log(myOrganisation) 

      if(isNewOrg(existingOrgCode.indexOf(myOrganisation.orgCode))){ 
       //doInsert 
      } else { 
       //doUpdate 
      } 
     } 
    }); 
} 

function getExcelData(){ 
    //This gets data from an excel spreadsheet 
} 

function isNewOrg(orgCode){ 
    //Checks if orgCode is not -1 and returns true/false accordingly 
} 

function getOrganisationCode(callback){ 
    //Do a DB call to return all orgCodes 
    //SELECT orgCode FROM tOrg 
} 

function getAreaId(areaCode, callback){ 
    //Do a DB call to return an area id based on the code passed 
    //SELECT areaId FROM tAreas WHERE areaCode = @input_parameter 
} 
+1

このチュートリアルでは、非同期関数 - > https://blog.risingstack.com/asynchronous-javascript/ –

+0

の記述方法について説明します。「確かに、別のアクションが起こる前に何か起こってほしいときがほとんどです実行されました " - ほとんどの場合、あなたのデータベースが結果を返すのを待っていた新しいHTTP要求の受け入れを、あなたのWebサーバが止めることを望んでいません。ほとんどの場合、レスポンスを得るためにHTTPリクエストを待っている間に、ブラウザがページのユーザーインターフェイス全体をロックしたくない場合がほとんどです。 – Quentin

答えて

1

非同期呼び出しを行うと、操作は現在のコードフローと並行して実行されます。

asyncデータベース呼び出しを実行すると、プログラムはデータベースが完了するまで待機しません。これがコールバックが使用される理由です。

あなたは単純にデータベースに「おい、私にIDを教えてください。あなたが終わったら教えてください。私は他のものに取り組んでいきます。 その後、プログラムは引き続きgetAreaId関数から抜け出します。しばらくしてから、データベース「おい、ここにIDです。コールバック関数にidを渡します。

organisationObj 
    --> getAreaId 
     | --> db call 
    <-- |   | 
...    | 
...    | 
(callback) <------| 
+0

あなたの説明を書いた方法私は今、「コールバック」の意味をよりよく理解しています。しかし、私は今コールバックが私がこれに近づくべき方法ではないと感じます、これは正しいでしょうか?もしそうなら、これに最も近づく方法は? –

+0

この場所でコールバックは絶対に正しいです。あなたがそのトピックに深く関わった場合、いわゆる「遅延結果」があるかもしれません。しかし、内部では、常にコールバックが使用されます。 –

1

Rita Saxenaは、非同期の説明に役立つリンクを共有しています。

コードの主な問題は、ループ内に非同期呼び出しのgetAreaIdがあることです。

この

for(var i = 1; i <= 5; i++) { 
    setTimeout(function() { 
    console.log('Value of i : ' + i); 
    },100); 
} 

あなたは出力に含まをすることを期待する機能について考える、(RiyaのSaxenaに加え、共有など)非同期概念を理解するための一般的な説明より:

Value of i : 1 
Value of i : 2 
Value of i : 3 
Value of i : 4 
Value of i : 5 

しかし、実際の出力は:

Value of i : 6 
Value of i : 6 
Value of i : 6 
Value of i : 6 
Value of i : 6 

これは、時間がsetTimeoutが評価されると、ループが終了し、ループ評価の最後にの値がのままになります。

この例は、この質問に答えないさまざまな方法で修正することができます。時間によってにconsole.log(myOrganisation)が評価され、あなたの場合は

は、

myOrganisation = new organisationObj(myDataSet[j]['OrgCode'], 
        myDataSet[j]['OrgName'], myDataSet[j]['orgName'], 
        myDataSet[j]['areaCode']); 

は、一般的なガイドラインとしてその評価(デシベルコール)

から返されていない場合には注意が必要ループと非同期呼び出しのミキシング。

関連する問題