2013-05-29 52 views
66

Kịch bản: Hãy xem xét phần sau đây là một phần của mã từ một ứng dụng web nút.Khi nào sử dụng next() và trả về next() trong Node.js

app.get('/users/:id?', function(req, res, next){ 
    var id = req.params.id; 
    if (id) { 
     // do something 
    } else { 
     next(); //or return next(); 
    } 
}); 

Issue: Tôi đang kiểm tra cái nào đi với chỉ next() hoặc return next(). Mã mẫu ở trên hoạt động chính xác như nhau cho cả & không hiển thị bất kỳ sự khác biệt nào trong việc thực thi.

Câu hỏi: Có thể một số ánh sáng một đặt về vấn đề này, khi sử dụng next() và khi nào sử dụng return next() và một số khác biệt quan trọng?

Trả lời

63

Một số người luôn viết return next() là để đảm bảo rằng việc thực hiện dừng lại sau khi kích hoạt gọi lại.

Nếu bạn không làm điều đó, bạn có nguy cơ kích hoạt cuộc gọi lại lần thứ hai sau, thường có kết quả tàn phá. mã của bạn là tốt như nó có, nhưng tôi sẽ viết lại nó như:

app.get('/users/:id?', function(req, res, next){ 
    var id = req.params.id; 

    if(!id) 
     return next(); 

    // do something 
}); 

Nó tiết kiệm cho tôi một mức độ thụt đầu dòng, và khi tôi đọc mã lại sau, tôi chắc chắn rằng không có cách nào next được gọi là hai lần .

35

next() là một phần của connect middleware. Các cuộc gọi lại cho luồng bộ định tuyến không quan tâm nếu bạn trả lại bất kỳ thứ gì từ các chức năng của mình, vì vậy, return next()next(); return; về cơ bản giống nhau.

Trong trường hợp bạn muốn ngăn chặn dòng chảy của các chức năng bạn có thể sử dụng next(err) như sau

app.get('/user/:id?', 
    function(req, res, next) { 
     console.log('function one'); 
     if (!req.params.id) 
      next('No ID'); // This will return error 
     else 
      next(); // This will continue to function 2 
    }, 
    function(req, res) { 
     console.log('function two'); 
    } 
); 

Khá nhiều next() được sử dụng cho việc mở rộng trung các yêu cầu của bạn.

+0

Chúng tôi có thể gửi tham số như sau: 'next ('No ID')'? –

+5

'next ('No ID')' thực sự đang gửi một lỗi, điều này sẽ phá vỡ dòng chảy. – drinchev

+0

Sử dụng tiếp theo (null, "somevalue"); Đối với các công cụ như async.waterfall, nó sẽ chuyển giá trị cho hàm tiếp theo. Đối với chuỗi tương tác phức tạp được điều khiển dữ liệu, tôi thường chuyển đối tượng ngữ cảnh giữa các hàm. Bằng cách đó tôi có thể tạo các hàm chung có thể được chia sẻ trên nhiều điểm kết thúc và kiểm soát luồng thông qua dữ liệu trong ngữ cảnh –

28

Như @Laurent Perrin của câu trả lời:

Nếu bạn không làm điều đó, bạn có nguy cơ gây ra gọi lại lần thứ hai sau, mà thường có kết quả tàn phá

tôi đưa ra một ví dụ ở đây nếu bạn viết trung như thế này:

app.use((req, res, next) => { 
    console.log('This is a middleware') 
    next() 
    console.log('This is first-half middleware') 
}) 

app.use((req, res, next) => { 
    console.log('This is second middleware') 
    next() 
}) 

app.use((req, res, next) => { 
    console.log('This is third middleware') 
    next() 
}) 

bạn sẽ tìm thấy ra rằng sản lượng trong giao diện điều khiển là:

This is a middleware 
This is second middleware 
This is third middleware 
This is first-half middleware 

Tức là, nó chạy mã bên dưới() sau khi tất cả chức năng phần mềm trung gian kết thúc.

Tuy nhiên, nếu bạn sử dụng return next(), nó sẽ thoát khỏi cuộc gọi lại ngay lập tức và mã bên dưới return next() trong cuộc gọi lại sẽ không thể truy cập được.

+1

Là một người mới bắt đầu để 'thể hiện 'câu trả lời này làm cho mọi thứ rõ ràng hơn với tôi hơn các câu trả lời khác. Thumbs up! – mandarin