2016-03-20 17 views
5

Tôi hiện đang làm việc trên một số tính toán khoa học mà các vòng tính toán cơ sở của tôi được thực hiện lặp đi lặp lại với các cuộc gọi đệ quy miễn là ít nhất một tham số là sai.Các cuộc gọi chức năng giới hạn trong các nút trên cùng một hoạt động?

Hiện tại máy chủ nodejs của tôi dừng lại ở khoảng 905 - 915th gọi hàm đệ quy.

Điều kỳ lạ là, nó không bị lỗi, cũng không xuất ra bất kỳ lỗi nào. Nó chỉ dừng lại làm bất cứ điều gì -> không có nhiều nhật ký, vv

Đây có phải là một số hành vi bảo vệ khỏi nút để tránh tràn không?

Tôi đang đấu tranh với điều này trong một vài tuần nay trong khi cố gắng giới hạn "vòng" với phần mềm thông minh nhất có thể.

Cảm ơn sự giúp đỡ của bạn & lời khuyên. Chúc mừng Noa.

Theo yêu cầu tôi cung cấp một số trừu tượng của mã thực tế của tôi

Tôi hy vọng điều này sẽ giúp. Tôi không thể đặt mã ban đầu của tôi ở đây vì nó bao gồm hơn 1.5k dòng - có rất nhiều thứ để kiểm tra. Nhưng ví dụ bên dưới bao gồm logic cơ sở đằng sau cuộc gọi đệ quy.

// Contains objects which contain an array 
// which represents the amount of the ex_obj terms 
var amount = { 
    a:[10,10], 
    b:[7.5,7.5], 
    c:[2.5,2.5,2.5,2.5] 
} 

// Contains objects, which contain an array of other objects 
// that represent some selection 
// Each object in an array consists of different values per attribute per 1 amount 
var ex_obj = { 
    a: [ 
    {aa: 1.41, ab: 0.143, ac: 0.5}, 
    {aa: 1.30, ab: 1.43, ac: 0.42} 
    ], 
    b: [ 
    {aa: 0.32, ab: 5.54, ac: 1.3}, 
    {aa: 0.33, ab: 4.49, ac: 2.5} 
    ], 
    c: [ 
    {aa: 0.54, ab: 1.4, ac: 3.5}, 
    {aa: 0.39, ab: 1.434, ac: 3.91}, 
    {aa: 0.231, ab: 1.44324, ac: 2.91}, 
    {aa: 0.659, ab: 1.554, ac: 3.9124}, 
    ] 
} 

// Here we have an object that represents 
// the "to be" state which should be achieved 
var should_be ={ 
    aa: 14.534, 
    ab: 3.43, 
    ac: 5.534 
} 

function calculate(){ 
    // Now we want to mulitply the amount object values with 
    // the ex_obj values 

    for(let prop in ex_obj){ 
    for(let i = 0, i < ex_obj[prop].length, i++){ 
     for(let propa in ex_obj[prop][i]){ 
     // here every aa,ab,ac gets mulitplied with the 
     // contains of the amount obj for the matching 
     // propertyname 
     } 
    } 
    } 

    // the next step is to check if the sum of all ex_obj property 
    // child values per aa, ab and ac match the should_be propertie values 

    // if everything is above the should_be and not too high then the 
    // programm can stop here and print out the amount obj. 

    // if the sum of the ex_obj properties is too little 
    // compared to the should_be obj 
    // we need to check which property is too little 
    // e.g. aa is too little 
    // then we check where aa in the ex_obj per 1 value is 
    // the highest 
    // then we increment the matching amount property child 
    // and start calculate() again 

    // same procedure for - if something is too much 
} 
+1

Nút làm cho việc thay thế các cuộc gọi đệ quy bằng các cuộc gọi không đồng bộ tương đối đơn giản và tránh hoàn toàn phát triển stack. Cung cấp thêm chi tiết và mã mẫu ... – Amit

+0

Tôi khá nghi ngờ chúng tôi có thể giúp bạn mà không cần nhìn thấy mã. Stack overflow thực sự tốt với các câu hỏi có chứa mã thực và không tốt lắm với các câu hỏi khái niệm không có mã. – jfriend00

+0

Tôi đã cập nhật Câu hỏi –

Trả lời

5

Vì mã của bạn không hoàn chỉnh, thật khó để nói chính xác điều gì đang xảy ra. Nếu bạn vượt quá giới hạn ngăn xếp cuộc gọi của nút, bạn sẽ nhận được ngoại lệ, mặc dù 1000 lần thu thập thông thường không phải là vấn đề.

Có thể bạn đang nghẹt thở vòng lặp sự kiện Node.js. Thay vì trực tiếp gọi hàm đệ quy, bạn có thể thử để gọi

process.nextTick(function(){calculate()}) 
+0

Cảm ơn bạn tôi sẽ thử phương pháp đó ngay hôm nay! –

+0

Nó không ngừng thực hiện chức năng nữa nhưng kết thúc bằng vòng lặp vô tận - đó có thể là lý do tại sao cuộc gọi chức năng mặc định bị dừng sau một vài vòng mà không có bất kỳ mẫu nào khác. –

+0

Vui mừng điều này có thể đã chỉ cho bạn đúng hướng –

1

Nó không ngạc nhiên rằng cuộc gọi đệ quy trực tiếp sẽ dẫn đến stack overflow, tuy nhiên, có vẻ như các cuộc gọi chức năng thường xuyên sẽ nhận được nút ngắt kết nối (BTW, tôi Không biết tại sao điều này xảy ra :()

Ví dụ: tập lệnh sau bị đóng băng ở khoảng 4k ~ 5k vòng trên máy tính của tôi với CPU 1.6 GHz và bộ nhớ 3.3 GiB, và nút tiếp tục nuốt bộ nhớ khả dụng của tôi sau đó .

var i = 0; 
function cal() { 
    console.log(++i); 
    process.nextTick(cal); 
} 
cal(); 

Nhưng nếu tôi thay đổi process.nextTick(cal); đến setTimeout(cal, 0);, mọi thứ đều hoạt động tốt.

Vì vậy, đối với câu hỏi của bạn, tôi nghĩ bạn có thể sử dụng một cái gì đó như setTimeout(calculate, 100) trong tập lệnh của bạn để ngăn chặn cuộc gọi đệ quy và trì hoãn nó một chút.

+0

Process.nextTick đã làm điều đó cho tôi.Mặc dù tôi kết thúc trong một vòng lặp vô tận bây giờ - nhưng đó có thể là một lỗi lập trình về phía tôi. :) –

Các vấn đề liên quan