2016-08-24 50 views
0

下面的代碼工作。該代碼調用API來獲取歷史交易(每次交易100次交易)。因爲有一個限制 - 允許調用API的頻率和頻率 - 結構就像遞歸一樣。遞歸java腳本函數 - 失控

流程是這樣的:

  1. 獲取當前MAX tradeId - 這是存儲在數據庫中。
  2. 現在用startIndex = MaxId做一個新的PULL,長度爲100(拉100個新交易)。
  3. 首先,當調用回調函數時,主代碼會繼續執行,並且有100個新的交易被拉出......等等。等。

所以......

代碼應該表現得像 - Psydo代碼

var maxId = GetMaxIdFromDB(); 

Pull(maxId, 100, callback); 

function callback(){ 

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

Pull(maxId, 100, callback); 

} 

奇怪的事情,我的問題是:如何才能API函數「getProductTrades 「」被稱爲不止一次 - 其中我的光標變量包含SAME值 - 當它增加100(或每次有效數據元素的數量)時。

我在說/參考。特別是下面的行:

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時...哈哈... 我剛剛添加了一些日誌記錄測試...我看起來只有它,並始終返回,呼叫,返回,打電話...看這裏: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

發生在沒有數據時會發生。 如果返回的數據爲空,你永遠也達不到的線

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

,但你還是叫

pullTrades(cursor, 100); 

末。我不知道它是有意的還是一個實際的錯誤,所以我離開解決方案(現在應該是微不足道的),直到你。