Як змусити JavaScript обіцянку повернути щось інше, ніж обіцянку?


38

У мене є специфікація від клієнта для реалізації методу в модулі:

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

Якщо дано масив жанрів,

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

Ось метод скелету з обіцянкою:

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

  return promise;
};

Чи можна зробити обіцянку повернути дані, знайдені в жанрах? Чи є кращий спосіб досягти опису специфікації?


8
Обіцянки не "повертають" значення, вони передають їх до зворотного дзвінка (який ви надаєте .then ()). Специфікація для мене просто звучить заплутано. Напевно, намагаються сказати, що ви повинні робити resolve([genre1, genre2, ...]);всередині виконання обіцянки.
Іксрек

Відповіді:


40

Здається, ви не розумієте, як обіцянки використовуються. Ви повернете обіцянку. Потім, пізніше, коли ваш код вирішить обіцянку, він вирішить його результатом, і цей результат передається .then()обробнику, приєднаному до обіцянки:

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
});

5
Це підтверджує, що обіцянки працюють так, як я очікував.
морський

Напевно, ви не розумієте, чому це може знадобитися. У такому середовищі, як React Native with Redux з Realm, я повинен передати початковий стан Redux createStore. Він повинен бути отриманий від Царства, але він повертає обіцянку. Я просто хочу заблокувати, поки він не поверне дані, оскільки це має бути дуже швидким і простим. Натомість у мене виникають проблеми, як поєднувати обіцянки Realm та звичайний об’єкт JSON для createStore ()
likern

26

Оновлена ​​версія, awaitа не використання .then().

awaitприпиняє виконання, поки Обіцяння не вирішиться (тобто не має значення). На відміну від використання, .then()ви можете просто зберігати awaitзначення, коли ви виконуєте різні функції, які повертають обіцянки, а виконання продовжується на наступний рядок (це називається "прямий стиль). Це також набагато приємніше дивитися, оскільки це відповідає решті JavaScript, ніж .then()скрізь.

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

Очікування підтримується у всіх поточних браузерах та вузлах


1
О, так, дивіться, 3 SE питання на цю тему, і, нарешті, ми маємо фактичну відповідь!
Андрій
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.