Avoiding exceeding call stack size in Node.JS with Mongoose
I'm relatively new to Node, so please do point any and all errors you see out.
I'm trying to write a relatively simple application; take JSON string of ~1k objects, split them up into groups and calculate a total of a specifical value in each object for that group. Problem is, I need the total to be precise down to quite a few decimals, and as such, I'm using BigDecimal (which I believe is what causes the many calls).
I get the following error:
RangeError: Maximum call stack size exceeded
I understand that this error comes from a function calling a function, so on and so forth, until the chain has become long enough to likely be an infinite loop. However, this also seems to be triggered by my function below.
I'm honestly stomped, and not quite sure how to work around this. With a callback-based application such as Node, you'd think there was well established standards for how to work around the call stack size. Unfortunately, my searching has found nothing. Any help would be greatly appreciated.
Code is as follows:
// 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;
}
}
}
链接地址: http://www.djcxy.com/p/71690.html