Jak sprawić, aby obietnica JavaScript zwróciła coś innego niż obietnica?

38

Mam specyfikację od klienta dotyczącą implementacji metody w module:

 // getGenres():
 //  Returns a promise. When it resolves, it returns an array.

Jeśli podano szereg gatunków,

['comedy', 'drama', 'action']

Oto szkieletowa metoda z obietnicą:

MovieLibrary.getGenres = function() {
  var promise = new Promise(function(resolve, reject) {
    /* missing implementation */
  });

  return promise;
};

Czy można złożyć obietnicę zwrotu danych znalezionych w gatunkach? Czy istnieje lepszy sposób na uzyskanie opisu specyfikacji?

sealocal
źródło
8
Obietnice nie „zwracają” wartości, przekazują je do wywołania zwrotnego (które podajesz za pomocą .then ()). Specyfikacja wydaje mi się po prostu zdezorientowana. Prawdopodobnie próbuje powiedzieć, że powinieneś zrobić to resolve([genre1, genre2, ...]);w ramach realizacji obietnicy.
Ixrec

Odpowiedzi:

40

Wygląda na to, że nie rozumiesz, w jaki sposób wykorzystywane są obietnice. Zwracasz obietnicę. Następnie, gdy Twój kod rozwiązuje obietnicę, rozwiązuje ją z wynikiem i ten wynik jest przekazywany do modułu .then()obsługi dołączonego do obietnicy:

MovieLibrary.getGenres = function() {
  var promise = new Promise(function(resolve, reject) {
    /* missing implementation */
    resolve(result);
  });

  return promise;
};

MovieLibrary.getGenres().then(function(result) {
    // you can access the result from the promise here
});
jfriend00
źródło
5
To potwierdza, że ​​obietnice działają tak, jak się spodziewałem.
sealocal
Prawdopodobnie nie rozumiesz, dlaczego może to być potrzebne. W środowisku, takim jak React Native z Redux z Realm, muszę ustawić stan początkowy w Redux createStore. Powinien zostać pobrany z Królestwa, ale zwraca obietnicę. Chcę tylko blokować, dopóki nie zwróci danych, ponieważ powinno to być bardzo szybkie i proste. Zamiast tego mam problemy z połączeniem obietnic Realm i zwykłego obiektu JSON dla createStore ()
podobnie
26

Zaktualizowana wersja za pomocą awaitzamiast .then().

awaitprzestaje działać, dopóki obietnica nie zostanie rozwiązana (tzn. ma wartość). W przeciwieństwie do używania .then(), możesz zachować awaitwartości podczas uruchamiania różnych funkcji, które zwracają obietnice, a wykonywanie jest kontynuowane w następnym wierszu (jest to nazywane „stylem bezpośrednim”). Jest też o wiele ładniej wyglądać, ponieważ jest zgodny z resztą JavaScript, niż .then()wszędzie.

// Example function that returns a Promise that will resolve after 2 seconds
var getGenres = function() {
  return new Promise(function(resolve) {
    setTimeout(function(){
      resolve(['comedy', 'drama', 'action'])
    }, 2000);
  });
}

// We start an 'async' function to use the 'await' keyword
(async function(){
  var result = await getGenres()
  console.log('Woo done!', result)

  // But the best part is, we can just keep awaiting different stuff, without ugly .then()s
  var somethingElse = await getSomethingElse()
  var moreThings = await getMoreThings()
})()

Oczekiwanie jest obsługiwane we wszystkich obecnych przeglądarkach i węźle

mikemaccana
źródło
1
Och, hej wow, spójrz, 3 pytania SE na ten temat i wreszcie mamy faktyczną odpowiedź!
Andrew