Что означают двойные скобки в javascript и как к ним обращаться
ситуация
У меня есть следующая функция, которая использует Promise.
var getDefinitions = function() {
return new Promise(function(resolve) {
resolve(ContactManager.request("definition:entities"));
});
}
var definitions = getDefinitions()
Содержание definitions
:
Promise {
[[PromiseStatus]]: "resolved",
[[PromiseValue]]: child
}
Доступ к свойству PromiseValue
напрямую возвращает неопределенное
var value = definitions.PromiseValue; // undefined
Вопрос
Что означают двойные скобки [[ ]]
и как получить значение [[PromiseValue]]
.
Ответы
Ответ 1
Что внутри [[]]
Мой вопрос в том, что означают двойные скобки [[]] и как я могу получить значение [[PromiseValue]].
Это внутреннее свойство. Вы не можете получить к нему доступ напрямую. Родной promises может быть развернут только в then
с promises или асинхронно в целом - см. Как вернуть ответ от асинхронного вызова. Цитирование спецификации:
Они определяются этой спецификацией исключительно для пояснительных целей. Реализация ECMAScript должна вести себя так, как если бы она создавалась и управлялась внутренними свойствами описанным здесь способом. Имена внутренних свойств заключены в двойные квадратные скобки [[]]. Когда алгоритм использует внутреннее свойство объекта, и объект не реализует указанное внутреннее свойство, генерируется исключение TypeError.
Вы не можете
Серьезно, хотя - что это?
Очень приятно! В приведенной выше цитате говорится, что они просто используются в спецификации - поэтому нет причин для их появления на консоли.
Не говорите никому, но это действительно личные символы. Причина, по которой они существуют, заключается в том, что другие внутренние методы могут иметь доступ к [[PromiseValue]]
. Например, когда io.js решает вернуть promises вместо принятия обратных вызовов - это позволит ему быстро получить доступ к этим свойствам в тех случаях, когда это гарантировано. Они не подвергаются воздействию снаружи.
Могу ли я получить к ним доступ?
Нет, если вы не создадите собственную версию Chrome или V8. Возможно, в ES7 с модификаторами доступа прямо сейчас нет способа, поскольку они не являются частью спецификации и будут разбиваться на браузеры - извините.
Итак, я получаю мою ценность?
getDefinitions().then(function(defs){
//access them here
});
Хотя, если бы мне пришлось угадать - вы не должны правильно преобразовывать API, чтобы начать с, поскольку это преобразование будет работать только в том случае, если метод является синхронным (в этом случай не возвращает обещание), или он возвращает обещание, которое уже разрешит (что означает, что вам вообще не требуется преобразование - просто return
.
Ответ 2
Сегодня я также столкнулся с этой проблемой и нашел решение.
Мое решение выглядит так:
fetch('http://localhost:3000/hello')
.then(dataWrappedByPromise => dataWrappedByPromise.json())
.then(data => {
// you can access your data here
console.log(data)
})
Здесь dataWrappedByPromise
является экземпляром Promise
. Чтобы получить доступ к данным в экземпляре Promise
, я обнаружил, что мне просто нужно развернуть этот экземпляр с помощью .json()
.
Надеюсь, это поможет!
Ответ 3
Этот пример относится к реакции, но по большей части он должен быть таким же.
Замените this.props.url своим URL-адресом, чтобы он работал для большинства других фреймворков.
Разбор res.json() возвращает [[promValue]], однако, если вы затем вернете его другому методу .then() ниже, вы можете вернуть его как полный массив.
let results = fetch(this.props.url)
.then((res) => {
return res.json();
})
.then((data) => {
return data;
})
Ответ 4
Чтение manpage, мы можем видеть, что:
По дизайну мгновенное состояние и ценность обещания не могут быть проверяется синхронно от кода, не вызывая метод then()
.
Чтобы помочь в отладке, только при проверке объекта обещания вручную, вы можете увидеть больше информации как специальные свойства, которые недоступный из кода (этот, в настоящее время, реализуется рандомизация имени свойства, из-за отсутствия более сложных язык или отладчик).
Акцент мой. Поэтому то, что вы хотите сделать, не может быть сделано. Лучший вопрос, почему вам нужно получить доступ к этому обещанию?
Ответ 5
Вот способ получить доступ к PromiseValue
(promise
):
let promises = definitions;
Promise.all(promises).then((promise) => {
console.log('promises = ', promises);
console.log('promise = ', promise);
});
Ответ 6
Я думаю, что с этим все будет хорошо.
(async () => {
let getDefinitions = await ( () => {
return new Promise( (resolve, reject) => {
resolve(ContactManager.request("definition:entities"));
});
})();
)();
Ответ 7
Небольшое изменение/расширение предоставленных решений
Для случая, когда ответом является HTML, а не JSON
fetch('http://localhost:3000/hello')
.then(response => response.text())
.then(data => {
// you can see your PromiseValue data here
console.log(data)
})
Ответ 8
Попробуйте использовать await.
Вместо
var value = definitions.PromiseValue
использование
var value = await definiton;
Это может решить вашу цель путем получения значения обещания.
Обратите внимание, что await можно использовать только внутри асинхронных функций, и это функция ES2016.