javascript - 递归 javascript 函数 - 失控

标签 javascript node.js recursion

下面的代码有效。该代码调用 API 来获取历史交易(每次拉取 100 笔交易)。因为存在限制 - 允许调用 API 的次数和频率 - 结构类似于递归。

流程如下:

  1. 获取当前的 MAX tradeId - 存储在数据库中。
  2. 现在创建一个新的 PULL,startIndex = MaxId,长度为 100(以拉取 100 个新交易)。
  3. 首先,当调用回调函数时,主代码将继续,并拉取 100 个新交易……等等。等等。

所以...

代码应该表现得像 - Psydo-code

var maxId = GetMaxIdFromDB();

Pull(maxId, 100, callback);

function callback(){

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

Pull(maxId, 100, callback);

}

奇怪的是,我的问题是:如何多次调用 API 函数“getProductTrades” - 我的光标变量包含SAME value - 当它增加 100(或每次有效数据元素的数量)时。

我正在说话/引用。特别是以下几行:

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

insertQuery.InsertMatchMsgArrayToDB(allData);方法调用另一个返回 promise 的数据库方法。

您可以在此处查看问题的屏幕截图: 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);
            } }};

最佳答案

当您从 getProductionTrades 中没有获取任何数据时,就会发生这种情况。 如果返回的数据为空,则永远不会到达行

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

但你还是打电话

pullTrades(cursor, 100);

在最后。我不知道这是有意为之还是实际错误,因此我将解决方案(现在应该很简单)留给您。

关于javascript - 递归 javascript 函数 - 失控,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39128550/

相关文章:

javascript - Node 和 Node js 之间有什么区别?

node.js - node.js 中的 http.createserver 与 net.createserver

javascript - 如何为 Node.js 中的 post 模块修复 "ReferenceError: xxx is not defined"

javascript - 合并对象之间的数据,匹配键值

javascript - 在 Canvas 上添加不同的平行线

JavaScript 递归奇怪的行为?

C递归头文件包含问题?

java - 生成字符串按空格的所有组合

javascript - 如何动态地向图像添加自定义文本输入

javascript - api.get(...).then(...).catch(...).finally 不是函数