Wie bringe ich ein JavaScript-Versprechen dazu, etwas anderes als ein Versprechen zurückzugeben?

38

Ich habe eine Spezifikation von einem Client für die Implementierung einer Methode in einem Modul:

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

Wenn eine Reihe von Genres gegeben,

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

Hier ist eine Skelettmethode mit einem Versprechen:

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

  return promise;
};

Kann das Versprechen gegeben werden, die in den Genres gefundenen Daten zurückzugeben? Gibt es einen besseren Weg, um die Spezifikationsbeschreibung zu erhalten?

sealocal
quelle
8
Versprechungen geben keine Werte zurück, sondern übergeben sie an einen Rückruf (den Sie mit .then () angeben). Die Spezifikation klingt für mich einfach verwirrt. Es wird wahrscheinlich versucht zu sagen, dass Sie resolve([genre1, genre2, ...]);innerhalb der Versprechen-Implementierung tun sollen .
Ixrec

Antworten:

40

Es hört sich so an, als ob Sie nicht verstehen, wie Versprechen verwendet werden. Du gibst ein Versprechen zurück. Später, wenn Ihr Code das Versprechen auflöst, löst er es mit einem Ergebnis auf und dieses Ergebnis wird an den .then()Handler übergeben, der an das Versprechen angehängt ist:

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
quelle
5
Dies bestätigt, dass Versprechen so funktionieren, wie ich es erwartet hatte.
Sealocal
Wahrscheinlich verstehen Sie nicht, warum dies erforderlich sein könnte. In Umgebungen wie Reagiere Native mit Redux mit Realm muss ich Redux createStore in den Anfangszustand versetzen. Es sollte aus dem Reich geholt werden, aber es gibt ein Versprechen zurück. Ich möchte nur blockieren, bis es Daten zurückgibt, da dies sehr schnell und einfach sein sollte. Stattdessen bekomme ich Probleme, wie man Realm-Versprechen und das übliche JSON-Objekt für createStore ()
kombiniert
26

Aktualisierte Version mit awaitanstatt .then().

awaitUnterbricht die Ausführung, bis das Versprechen aufgelöst wurde (dh einen Wert hat). Im Gegensatz zur Verwendung können .then()Sie awaitWerte einfach beibehalten, während Sie verschiedene Funktionen ausführen, die Versprechungen zurückgeben, und die Ausführung in der nächsten Zeile fortsetzen (dies wird als direkter Stil bezeichnet). Es ist auch viel schöner anzusehen, da es mit dem Rest von JavaScript konsistent ist, als .then()überall.

// 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()
})()

Warten wird in allen aktuellen Browsern und Nodes unterstützt

Mikemaccana
quelle
1
Oh hey wow schau, 3 SE Fragen zu diesem Thema und endlich haben wir eine tatsächliche Antwort!
Andrew