Можно ли использовать одно ключевое слово await для разрешения набора последовательных обещаний? - PullRequest
1 голос
/ 04 мая 2020

Возможно, это ограничение языка, но я пытаюсь выяснить, как мне избежать использования одного ключевого слова await для набора последовательных разрешений обещаний. Я пытаюсь добиться чего-то удобочитаемого, например:

const workoutExercises = await Workout.get(1).workoutExercises;

Workout.get обращается к базе данных и возвращает Promise. Обещание разрешается до экземпляра Workout, который имеет метод get ter в экземпляре с именем workoutExercises, который также является Promise, который разрешается в массив WorkoutExercise s.

Приведенный выше код не работает и ожидает только Workout.get разрешения; также не ждет разрешения .workoutExercises. Приведенные ниже примеры кода DO работают, но я пытаюсь добиться однострочности / большей читабельности:

1:

const workoutExercises = await (await Workout.get(1)).workoutExercises;

2:

const workout = await Workout.get(1);
const workoutExercises = await workout.workoutExercises;

Редактировать # 1 Обновлены заголовок и описание, чтобы пояснить, что проблема заключается не в разрешении цепочки Обещаний, а в разрешении Обещания, основанном на разрешении предыдущего Обещания.

Workout.get --> <Promise> --> workout --> .workoutExercises --> <Promise> -> desired result

Ответы [ 2 ]

1 голос
/ 04 мая 2020

Используйте .then() по результатам .get(1) и извлеките workoutExercises. Один вкладыш очень удобочитаемый.

Пример:

(async() => {

  const Workout = {
    get: () => Promise.resolve({
      workoutExercises: Promise.resolve(3)
    })
  };

  const workoutExercises = await Workout.get(1).then(w => w.workoutExercises);

  console.log(workoutExercises)

})()
0 голосов
/ 04 мая 2020

Можно ли использовать одно ключевое слово await для разрешения набора последовательных обещаний

Поскольку эти обещания на самом деле не связаны, это не так. У вас есть обещание, которое разрешается для объекта, обладающего свойством, которое при обращении к нему имеет геттер, который создает новое обещание, которое разрешается до значения, которое вы, наконец, хотите. Это два совершенно разных обещания, и вам придется использовать await или .then() для каждого из двух, так что вы не можете сделать это с одним await.

Вы можете использовать небольшое вмешательство код, чтобы связать их вместе и даже поместить в вспомогательную функцию:

function getWorkoutExercises(n) {
    return Workout.get(n).then(workout => {
        // chain this promise to the previous one
        return workout.workoutExercises;   
    });
}

// usage
getWorkoutExercises(1).then(exercises => {
    console.log(exercises);
}).catch(err => {
    console.log(err);
});

или

// usage
try {
    let exercises = await getWorkoutExercises(1);
    console.log(exercises);
} catch(e) {
    console.log(e);
}
...