2015-10-05 10 views
10

Mam poniżej kod, którego używam w mojej aplikacji Express.js do scentralizowania niektórych operacji acl. Jeśli funkcja zwraca true lub false jawnie oprogramowanie pośredniczące może obsłużyć wywołanie next. Ale jeśli nie powróci, to do autoryzowanej logiki, aby wykonać next(), gdy skończy się to robić.Wycieki pamięci Node.js?

Aby uniknąć konieczności wypisywania danych o błędach, chcę po prostu przekazać funkcję error(), która może być wywołana, która po prostu wywołuje funkcję wewnętrznie next.

Ktoś powiedział mi, że może to prowadzić do pewnych wycieków pamięci, ponieważ funkcja next znajduje się w swoim zamknięciu i odwołuje się do niej z zewnątrz. Widzę podobne techniki używane w wielu przykładach w Internecie, ale wciąż jestem nowy w Node.js, więc zastanawiam się, czy jest w tym jakaś prawda?

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: Usuń zmienne

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

Czy mogę zapytać, dlaczego chcesz, aby metoda autoryzacji obsługiwała wywołanie 'next'? Jaka sytuacja by się przydała? – shennan

Odpowiedz

4

Po skonfigurowaniu middleware, metoda .use() nazywa się tam raz, anonimowy handler/middleware są zapisywane w pamięci jeden raz, i to w tym samym funkcja middleware, która jest wywoływana dla każdego nowego żądania.

Zmienna jest tworzona przy każdym uruchomieniu oprogramowania pośredniego i jest to inny obiekt. Gdybyś umieścił go na zewnątrz w zakresie zamknięcia .use(), byłby to ten sam obiekt.

Jest następnie przekazywana do next i next jest bardzo prawdopodobne, że inna funkcja oprogramowania pośredniego zostanie raz utworzona i pozostanie taka sama w pamięci, która będzie się utrzymywać i będzie dostępna dla dostępu do zamknięcia.

Ale wtedy, gdy funkcja next kończy działanie, obiekt, który wskazuje err straciłby swoje referencje - powinien być zbierany śmieci.

+0

Hmm, nie jestem pewien, czy 'next' jest po prostu inną funkcją. Musi on w jakiś sposób mieć informacje o bieżącym żądaniu, aby nie zakłócać innych żądań. Tak jakbym zadzwonił do 'next', to musi wiedzieć, co jest" następne ". Tak więc istnieje kilka danych, które muszą być przechowywane na żądanie, które myślę. – Rob

+1

Istnieje pewien "niewidzialny" kod dodany przez Express, który przekazuje 'req',' res' itd. Do. Sekwencja procedur obsługi jest określana w kolejności, w której wykonano wywołanie '.use()', podobnie jak dodanie wywołań zwrotnych do sekwencji rurociągów. W pewnym momencie każde wywołanie oprogramowania pośredniego powinno zakończyć się, a te obiekty, do których odwołuje się, utracą swoje referencje i zostaną zebrane; nawet jeśli odwołasz się do nich w "następnym" oprogramowaniu pośredniczącym, w którymś momencie następna funkcja również powinna się zakończyć. –

Powiązane problemy