使用Mongoose避免在Node.JS中超出调用堆栈大小

时间:2014-02-04 18:42:05

标签: javascript node.js mongodb callstack

我对Node比较陌生,所以请指出你看到的所有错误。

我正在尝试编写一个相对简单的应用程序;获取~1k对象的JSON字符串,将它们分成组并计算该组的每个对象中的特定值的总和。问题是,我需要将总数精确地降低到相当多的小数,因此,我正在使用BigDecimal(我相信这是导致许多调用的原因)。

我收到以下错误:

RangeError: Maximum call stack size exceeded

我知道这个错误来自调用函数的函数,依此类推,直到链变得足够长以至于可能是无限循环。但是,这似乎也是由我的功能触发的。

我老老实实地说,并且不太确定如何解决这个问题。使用基于回调的应用程序(如Node),您会认为有很好的标准可以解决如何解决调用堆栈大小问题。不幸的是,我的搜索一无所获。任何帮助将不胜感激。

代码如下:

// Mongoose
mongoose.connect("mongodb://localhost/test");
var db = mongoose.connection;
db.on("error", console.error.bind(console, "connection error:"));

// If connection success
db.once("open", function() {
    // Define current period schema/model
    var Mixed = mongoose.Schema.Types.Mixed;
    var curSchema = mongoose.Schema({
        total: Mixed,
        startTime: { type: Number, default: 0 },
        lastTime: { type: Number, default: 0 },
        high: Mixed,
        low: Mixed 
    });
    var curModel = mongoose.model("curModel", curSchema);
    // Create current period
    currentPeriod = new curModel({total: new bigdecimal.BigDecimal("0"),
                                        high: new bigdecimal.BigDecimal("0"),
                                        low: new bigdecimal.BigDecimal("999") });

    curModel.find(function(err,current) {
            if (err) console.error("=== FAILED TO FIND CURRENT PERIOD! ===");
            console.log(current);
        });

    scraper.retrieve("[url-of-json]",{},
    updateOrders);
});

/* *
 * Update database with newest orders
 */
var updateOrders = function(error, r, body) {
    var response = JSON.parse(body);

    // Stop if retrieval failed
    if (error || !response || response.error) {
        console.log("Failed to retreive trade history:");
        console.log(error || response.error);
        return;
    }
    // Loop through every order, from bottom
    var k = Object.keys(response);
    for (var i = k.length - 1; i>=0; i--) {
        var j = k[i];
        var amount = new bigdecimal.BigDecimal(response[j].amount);
        var price = new bigdecimal.BigDecimal(response[j].price);

        // If we haven't logged this order yet (and it's in the current period)
        if (response[j].date >= currentPeriod.lastTime && response[j].date - currentPeriod.startTime < 900) {

            if (!(i%20)) console.log("Adding " + amount.toString() + " to total. Time: " + (response[j].date - currentPeriod.startTime) + ". I: " + i);
            currentPeriod.total = currentPeriod.total.add(amount);
            currentPeriod.lastTime = response[j].date;
            if (price.compareTo(currentPeriod.high)===1) currentPeriod.high = price;
            if (price.compareTo(currentPeriod.low)===-1) currentPeriod.low = price;
        }

        // If we've passed the 15-minute mark
        if (response[j].date - currentPeriod.startTime >= 900) {
            // If we should save
            if (currentPeriod.startTime !== 0) {
                console.log("=== Period end ("+response[j].date+") === ");
                console.log("End index: " + i);
                console.log("Total: " + currentPeriod.total.toString());
                console.log("High: " + currentPeriod.high.toString());
                console.log("Low: " + currentPeriod.low.toString());
                console.log("Closing: " + price);

                // Mark as modified
                currentPeriod.markModified("total");currentPeriod.markModified("lastTime");
                currentPeriod.markModified("startTime");currentPeriod.markModified("high");
                currentPeriod.markModified("low");
                // Save
                currentPeriod.save(function(err,period) {
                        if (err) console.error("=== Failed to save current period! ===");
                    });
            }

            currentPeriod.total = new bigdecimal.BigDecimal("0").add(amount);
            currentPeriod.lastTime = response[j].date;
            currentPeriod.startTime = response[j].date;
            currentPeriod.high = price;
            currentPeriod.low = price;
        }
    }
}

0 个答案:

没有答案