2016-08-24 6 views
0

以下のコードは機能します。このコードでは、過去の取引(pérを引き出すたびに100回の取引)を取得するAPIが呼び出されています。 APIを呼び出すことができる回数と頻度は制限があるため、構造は再帰的なものと同じです。再帰的なJavaスクリプト機能 - 制御外

流れは次のようである:

  1. が現在MAX tradeId取得 - DBに格納されます。
  2. startIndex = MaxId、長さ100の新しいPULLを作成します(100回の新しい取引を引き出すため)。
  3. 最初にコールバック関数が呼び出されてメインコードが呼び出され、100個の新しい取引が引き出されると、... ect。 ect。

そう...

コードが振る舞うべきのような - Psydoコード

var maxId = GetMaxIdFromDB(); 

Pull(maxId, 100, callback); 

function callback(){ 

... do different stuff.. 
maxId += 100; 

Pull(maxId, 100, callback); 

} 

奇妙なことと、私の質問は:どのようにAPI機能 "getProductTrades "は複数回呼び出すことができます - カーソル変数にはの値があります - 100(またはその都度有効なデータ要素の数)でインクリメントされます。

I'm talking/ref。特に、次の行に:

wl.debug("getProductTrades - cursor: " + cursor + " Limit: " + limit); 
       publicClient.getProductTrades({'after': cursor, 'limit': limit}, callback); 

insertQuery.InsertMatchMsgArrayToDB(ALLDATA)。メソッドは、約束を返す別のDBメソッドを呼び出します。

あなたがここでの問題のスクリーンショットを見ることができます: http://screencast.com/t/DH8rz3UxnyZ

実際のコードはここにある:

pullTradesBetween: function (minTradeId, maxTradeId) { 

      var wl = new WinLog(); 
      var tradeCounter = 0; 

      try { 
       var WebSocketEmit = new WSemitter(); 
       var startTime = new Date().toLocaleString(); 
       var executeTradePullAgain = null; 

       wl.debug("REST API START: " + startTime); 

       var cursor; 
       var incrementedCursorWith = 0; 

       if ((maxTradeId - minTradeId) < 100) { 
        cursor = maxTradeId + 1; 
       } 
       else 
        cursor = minTradeId + 100; 

       var callback = function (err, response, data) { 

        if (executeTradePullAgain !== null) 
         clearTimeout(executeTradePullAgain); 

        if (err) 
         wl.info("Err: " + err); 

        var validData = []; 
        incrementedCursorWith = 0; 

        if (response == null) 
         wl.info("RESPONSE ER NULL"); 

        if (data !== null) { 
         for (var i = data.length - 1; i >= 0; i--) { 
          var obj = data[i]; 

          var tradeId = parseInt(obj.trade_id); 

          if (obj !== null && (minTradeId <= tradeId && tradeId <= maxTradeId)) { 
           validData.push(data[i]); 
          } 
         } 

         if (validData.length == 0) { 
          wl.debug("Contains 0 elements!"); 
         } 
         else { 
          cursor = cursor + validData.length; 
          incrementedCursorWith = validData.length; 
          insertDataToDB(validData); 
         } 
        } 
        else 
         wl.debug("DATA IS NULL!"); 

        wl.debug("cursor: " + cursor + " maxTradeId: " + maxTradeId); 

        var diffToMax = maxTradeId - (cursor - incrementedCursorWith); 

        if (diffToMax >= 100) 
         pullTrades(cursor, 100); // 100 is default 
        else if (diffToMax >= 0) 
         pullTrades(maxTradeId + 1, diffToMax + 1); // X = Only the last trades in the given series of trades 
        else { 
         wl.info("REST API START: " + startTime + " REST API DONE: " + new Date().toLocaleString()); 

         WebSocketEmit.syncHistoricalDataDone(); 
        } 
       }; 

       function pullTrades(cursor, limit) { 

        tradeCounter += limit; 

        if(tradeCounter % 10000 == 0){ 
         wl.info('Downloaded: ' + tradeCounter + ' trades via REST API (Total: ' + cursor + ')'); 
        } 

        pullTradesAgainIfServerDoesNotRespond(cursor, limit); 

        wl.debug("getProductTrades - cursor: " + cursor + " Limit: " + limit); 
        publicClient.getProductTrades({'after': cursor, 'limit': limit}, callback); 
       } 

       function pullTradesAgainIfServerDoesNotRespond(cursor, limit) { 

        executeTradePullAgain = setTimeout(function() { 
         wl.debug('pullTradesAgainIfServerDoesNotRespond called!'); 
         pullTrades(cursor, limit); 
        }, 30000); 
       } 

       // SAVE DATA IN DB! 
       function insertDataToDB(allData) { 
        insertQuery.InsertMatchMsgArrayToDB(allData); 
       } 

       wl.debug("pull trades: " + cursor); 
       pullTrades(cursor, 100); 
      } 
      catch(err){ 
       wl.info('pullTradesBetween: ' + err); 
      } }}; 
+0

'publicClient.getProductTrades()は毎回一度だけコールバックを呼び出しますか? –

+0

API DOCはこれについて何も言わないが、APIが5 x 20のオブジェクトを返す場合は、私が100を要求すると、それはむしろ奇妙だと思うだろう。... haha​​ ... テスト...私はそれだけのように見え、いつも、コール、リターン、コールを返します。ここを見てください:http://screencast.com/t/YkGvgfBcOMqb – PabloDK

+0

これはここでのナイーブなポイントかもしれません...しかし'maxId - minId'が' 100'と保証するものは何ですか?貿易記入項目が削除されている可能性があります。これは実際には安全なもののようには見えません – axelduch

答えて

0

私はあなたのコード

pullTradesBetween: function (minTradeId, maxTradeId) { 
    var WebSocketEmit = new WSemitter(); // try-catch ? 
    var curr = (maxTradeId - minTradeId < 100) ? maxTradeId + 1 : minTradeId + 100; 

    // function always return data or infinite error-loop 
    function getProductTrades (after, limit, callback) { 
     // try-catch ? 
     publicClient.getProductTrades ({after, limit}, function(err, data) { 
      if (err) { 
       console.log(err); 
       return getTrades(after, limit, callback); 
      } 

      callback(null, data); 
     }); 
    } 

    function onDataReady (err, data) { 
     if (err) 
      throw new Error('Impossible!'); 

     if (!data || !(data instanceof Array)) 
      return ... smth on empty data ... 

     var validData = data.filter(function(obj) { 
      return obj && 
       minTradeId <= parseInt(obj.trade_id) && 
       parseInt(obj.trade_id) <= maxTradeId; 
     }).reverse(); 

     if (validData.length == 0) 
      return ... smth on empty data ... 

     insertDataToDB(validData); 

     curr += validData.length; // maybe +-1 

     var remaining = maxTradeId - curr; 
     if (remainig == 0) { 
      console.log('Done'); 
      // try-catch ? 
      WebSocketEmit.syncHistoricalDataDone(); 
     } 

     return (remaining >= 100) ? 
      getProductTrades(curr, 100, onDataReady) : 
      getProductTrades(maxTradeId + 1, remaining + 1, onDataReady); // ?? 
    } 

    getProductTrades(curr, 100, onDataReady); 
} 
1

を簡素化しようとしますそれはあなたがのデータを取得しないと起こります。 返されたデータがnullの場合は、行

cursor = cursor + validData.length; 
incrementedCursorWith = validData.length; 

に到達することはありませんが、あなたはまだ終わりで

pullTrades(cursor, 100); 

を呼び出します。私はそれが意図されているか実際のエラーかわからないので、私は解決策を残す(今は自明でなければならない)。

関連する問題