Получить значение разрешенного обещания в синхронизации - PullRequest
0 голосов
/ 22 ноября 2018

Если мы знаем, что Promise определенно разрешен, как мы можем получить доступ к значению, и если мы не можем, почему нет?

let a = Promise.resolve(123);

console.log(a.value); // ???

Следующее не работает - оно печатает «Сначала, Last, 123 "

console.log("First");
Promise.resolve(123).then(console.log);
console.log("Last");

Я спрашиваю, как получить значение уже разрешенного Promise синхронно и если это невозможно, то почему бы и нет?

Ответы [ 4 ]

0 голосов
/ 22 ноября 2018

Нет, это невозможно сделать.Это сделано специально.

Спецификация Promise A + предназначена для использования в качестве простого и согласованного способа решения асинхронных операций.Одно из ограничений заключается в том, что передача нового обратного вызова на then() для уже выполненного обещания будет всегда выполняться на более позднем тике в цикле событий, поэтому все будет согласованно.

Добавлениевторичный способ проверить результаты обещания не был бы невозможен.Вероятно, это было бы довольно легко сделать, но есть как минимум две проблемы с добавлением этого в спецификацию:

  1. Если вы хотите создать спецификацию, вы хотите, чтобы она была такой же простойнасколько это возможно.Сама спецификация фактически определяет только функцию then().
  2. Добавляя эту функцию, вы открываете дверь толпам разработчиков, которые еще больше запутываются в том, что уже трудно понять.

Обещания и асинхронные операции трудно понять людям.Я ежедневно вижу здесь вопросы об обещаниях, а не о том, как их получить.Если бы к обещанию по умолчанию был добавлен не асинхронный способ доступа к результатам обещания, я бы предположил, что это будет еще больше.Это хорошо, чтобы попытаться навязать «правильный путь» ведения дел.

Однако это решение не просто для вас.Вы не застряли там.Вы можете очень легко создать свою собственную версию обещания, которая имеет эту функцию и все еще работает с существующими обещаниями.Пока ваш объект имеет функцию then(), которая ведет себя в соответствии с Обещаниями / A +, вы можете делать с остальным объектом все, что захотите.

0 голосов
/ 22 ноября 2018

Обещания всегда являются асинхронными в JS.

Если вы уверены, что обещание будет разрешено, вы можете получить к нему доступ с помощью метода .then.

a.then(function(value) {
    console.log("First");
    console.log(value);
    console.log("Last");
    // expected output: 123
});

Переменная a будет выглядеть ниже, если она будет console.log

Promise {<resolved>: 123}
    __proto__: Promise
    [[PromiseStatus]]: "resolved"
    [[PromiseValue]]: 123

Для обработки ошибок вы можете заблокировать ошибку, как указано в MDN docs .

0 голосов
/ 22 ноября 2018

Вы можете использовать async/await синтаксис от ES7

(async () => {
  console.log("First");
  console.log(await Promise.resolve(123));
  console.log("Last");
})()

Помните, что await работает только внутри async функций

Объяснение «Почему вы не можете получить значение уже разрешенногоОбещание синхронно "

Отладка обещания

По своему замыслу мгновенное состояние и значение обещания не могут быть проверены синхронно из кода без вызоваМетод then ().

Чтобы помочь с отладкой, только при ручной проверке объекта обещания вы можете видеть дополнительную информацию в виде специальных свойств, недоступных из кода (в настоящее время это реализуется путем рандомизации имени свойства, из-за отсутствия более сложной поддержки языка или отладчика).

0 голосов
/ 22 ноября 2018
Promise.resolve(123).then(function(value) {
    console.log(value);
}

Взгляните на это

...