Подтвердить что ты не робот

Что означают двойные скобки в 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]].

4b9b3361

Ответ 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.