2015-10-05 50 views
10

Tôi có một số mã bên dưới mà tôi đang sử dụng trong ứng dụng Express.js để tập trung một số logic acl. Nếu hàm trả về true hoặc false rõ ràng phần mềm trung gian có thể xử lý cuộc gọi next. Nhưng nếu nó không trả lại, nó sẽ cho phép logic thực hiện next() bất cứ khi nào nó hoàn thành công việc của nó.Rò rỉ bộ nhớ Node.js?

Để tránh phải ghi dữ liệu lỗi, tôi chỉ cần chuyển một hàm error() có thể gọi, mà chỉ cần gọi hàm next nội bộ.

Một người nào đó nói với tôi rằng điều này có thể dẫn đến một số loại rò rỉ bộ nhớ vì chức năng next đang ở trạng thái đóng riêng và tham chiếu nó từ bên ngoài. Tôi thấy các kỹ thuật tương tự đang được sử dụng trong rất nhiều ví dụ trực tuyến, nhưng tôi vẫn còn khá mới với Node.js nên tự hỏi liệu có sự thật nào về điều này không?

this.router.use(function (req, res, next) { 
    var err = { 
      code: 403, 
      exception: 'UnauthorizedException', 
      data: {} 
     }, 
     error = function() { 
      next(err); 
     }, 
     authorize = app.route.authorize(req, res, next, error); 

    if (authorize === false) { 
     next(err); 
    } 
    else if (authorize === true) { 
     next(); 
    } 
}); 

EDIT: Di chuyển biến

this.router.use(function (req, res, next) { 
    var authorize = app.route.authorize(req, res, next, function() { 
     next({ 
      code: 403, 
      exception: 'UnauthorizedException', 
      data: {} 
     }); 
    }); 

    if (authorize === false) { 
     next({ 
      code: 403, 
      exception: 'UnauthorizedException', 
      data: {} 
     }); 
    } 
    else if (authorize === true) { 
     next(); 
    } 
}); 
+0

Tôi có thể hỏi tại sao bạn muốn phương thức ủy quyền xử lý cuộc gọi 'tiếp theo' không? Tình huống này có ích gì? – shennan

Trả lời

4

Khi bạn thiết lập các trung gian, phương pháp .use() được gọi là có một lần, xử lý vô danh/middleware được ghi vào bộ nhớ một lần, và đó là cùng chức năng trung gian được gọi cho mỗi yêu cầu mới.

Biến số err được khởi tạo mỗi khi phần mềm trung gian chạy và đó là một đối tượng khác. Nếu bạn đặt nó bên ngoài và vào phạm vi đóng cửa của .use(), thì nó sẽ là cùng một đối tượng.

Sau đó, nó được chuyển đến nextnext rất có thể là một chức năng phần mềm trung gian khác được khởi tạo một lần và vẫn giữ nguyên trong bộ nhớ vẫn tiếp tục truy cập.

Nhưng sau đó, khi chức năng next kết thúc chạy, đối tượng err điểm sẽ mất tham chiếu của nó - nó phải được thu gom rác.

+0

Hmm, tôi không chắc chắn, nếu 'next' chỉ là một hàm khác. Nó cần bằng cách nào đó có thông tin về yêu cầu hiện tại để không can thiệp vào các yêu cầu khác. Giống như nếu tôi gọi 'next' nó cần phải biết cái gì là "tiếp theo". Vì vậy, có một số dữ liệu cần được lưu trữ theo yêu cầu mà tôi nghĩ. – Rob

+1

Có một số mã "vô hình" được thêm bởi Express để chuyển 'req',' res', v.v. Trình xử lý được xác định theo thứ tự mà bạn đã thực hiện lệnh '.use()', nó giống như thêm các callback vào một chuỗi đường ống. Tại một thời điểm nào đó, mỗi cuộc gọi middleware sẽ kết thúc, và những đối tượng được tham chiếu đó sẽ mất đi các tham chiếu của chúng và thu gom rác; ngay cả khi bạn tham chiếu chúng trong phần mềm trung gian 'tiếp theo ', tại một thời điểm nào đó hàm tiếp theo cũng nên chấm dứt. –