2014-09-17 8 views
5

Piszę kod, który obecnie wygląda tak, ponieważ mam zależności w moim kodzie. Zastanawiam się, czy był to lepszy sposób na zrobienie tego za pomocą Promise.all()? Tu jest mój pseudo kod:Metoda Bluebird's Promise.all(), gdy jedna obietnica jest zależna od innej

 return someService.getUsername() 
      .then(function(username) { 
       user = username; 
      }) 
      .then(function() { 
       return someService.getUserProps(user); 
      }) 
      .then(function(userProps) { 
       userProperties = userProps; 
       return someService.getUserFriends(user); 
      }) 
      .then(function(userFriends) { 
       friends = userFriends; 
      }) 
      .catch(error) 
      .finally(function(){ 
       // do stuff with results 
      }); 

Ważną rzeczą jest to, że muszę użytkownika przed mogę zrobić kolejne dwa połączenia dla getUserProps() i getUserFriends(). Pomyślałem, że mogę użyć Promise.all() do tego tak:

var user = someService.getUsername() 
    .then(function(username) { 
     user = username; 
    }) 
var getUserProps = someService.getUserProps(user); 
var getUserProps = someService.getUserFriends(user); 

return Promise.all(user, getUserProps, getUserFriends, function(user, props, friends) { 
    // do stuff with results 
}) 

Ale nie mogę tego uruchomić. Czy to jest właściwy przypadek użycia .all?

Odpowiedz

8

Promise.all() jest przeznaczony do pracy równoległej, w której uruchamia się szereg operacji asynchronicznych uruchamianych w tym samym czasie, a następnie informuje, kiedy wszystkie są gotowe.

Nie ma sekwencji jeden w porównaniu do zakończenia innego w jakikolwiek sposób. Nie można go więc używać do czekania, aż użytkownik będzie gotowy, a następnie inne operacje będą używać tego użytkownika. Po prostu nie jest to zaprojektowane do tego.

Najpierw możesz uzyskać użytkownika, a kiedy wszystko będzie gotowe, możesz użyć Promise.all() z Twoimi dwoma innymi operacjami, które, moim zdaniem, mogą być uruchamiane w tym samym czasie i nie zależą od siebie nawzajem.

var user; 
someService.getUsername().then(function(username) { 
    user = username; 
    return Promise.all(getUserProps(user), getUserFriends(user)); 
}).then(function() { 
    // do stuff with results array 
}).catch(function() { 
    // handle errors 
}); 
4

Można użyć .all ale będziesz mieć pewność, że prowadzony kolejno swój kod, można to zrobić przez .then je ing jak zrobiłeś. Jeśli to zrobisz, powinieneś użyć .join, który jest skrótem dla .all([...]).spread(....

var user = someService.getUsername(); 
var props = user.then(getUserProps) 
var friends = user.then(getUserFriends) 
Promise.join(user, props, friends, function(user, props, friends) { 

    // everything is available here, everything is synchronized 
}); 

Jeśli to, co próbowaliście rozwiązać, to kwestia zamknięcia/zagnieżdżenia - to jest sposób, aby to zrobić.

+0

Nie działa to dla mnie, ponieważ muszę przekazać zmienną do getUserProps() i nie mam jej, gdy ustawiam zmienną rekwizytu w drugiej linii. – Jeff

+1

@Jeff zmienna użytkownika jest automatycznie przekazywana do funkcji getUserProps, ponieważ jest to wartość obietnicy - podobnie jak w twoim przykładzie. Możesz użyć '.bind', jeśli potrzebujesz przekazać dodatkowe parametry lub funkcję anonimową. –

+0

ohhh .... więc definicja rekwizytów mogła być: var props = user.then (getUserProps (user)); ? – Jeff

1

Promise.all() to sposób na równoległe wykonanie listy obietnic, ale jeśli chcemy wykonać listę obietnic w serii, w której jedna jest zależna od drugiej, musimy rozwiązać ją nieco inaczej

Powiązane problemy