80

情况

我有以下使用Promise的功能。

var getDefinitions = function() {
    return new Promise(function(resolve) {
        resolve(ContactManager.request("definition:entities"));
    });
}

var definitions = getDefinitions()

的内容definitions是:

Promise {
    [[PromiseStatus]]: "resolved",
    [[PromiseValue]]: child
}

直接访问PromiseValue属性返回undefined

var value = definitions.PromiseValue; // undefined

问题

双括号是什么[[ ]]意思,以及如何检索[[PromiseValue]].

4

7 回答 7

107

里面是什么东西[[]]

我的问题是双括号 [[ ]] 是什么意思,以及如何检索 [[PromiseValue]] 的值。

这是内部财产。您无法直接访问它。本机承诺只能通过then承诺或异步方式展开 - 请参阅如何从异步调用返回响应。引用规范:

它们由本规范定义,纯粹是为了说明目的。ECMAScript 的实现必须表现得好像它以此处描述的方式生成和操作内部属性。内部属性的名称用双方括号 [[ ]] 括起来。当算法使用对象的内部属性并且对象未实现指示的内部属性时,将引发 TypeError 异常。

你不能

不过说真的——它们是什么?

非常好!正如上面的引用所说,它们只是在规范中使用 - 所以它们没有理由真正出现在您的控制台中。

不要告诉任何人,但这些都是真正的私人符号。它们存在的原因是其他内部方法能够访问[[PromiseValue]]. 例如,当 io.js 决定返回 Promise 而不是采用回调时——这将允许它快速访问这些属性,以防万一。它们暴露在外面。

我可以访问它们吗?

除非您制作自己的 Chrome 或 V8 版本,否则不会。也许在带有访问修饰符的 ES7 中。截至目前,没有办法,因为它们不是规范的一部分,并且会跨越浏览器 - 抱歉。

那么如何获得我的价值呢?

getDefinitions().then(function(defs){
    //access them here
});

但是如果它返回一个错误呢?在这些情况下,在 .then() 的末尾(和外部)添加以下内容。

.catch(function(defs){
    //access them here
});

虽然如果我不得不猜测 - 你没有正确转换 API,因为这种转换只有在方法是同步的(在这种情况下不返回承诺)或它已经返回承诺的情况下才有效,这将使它解决了(这意味着您根本不需要转换 - 只是return.

于 2015-03-07T16:34:05.590 回答
18

我今天也走进了这个问题,碰巧找到了解决方案。

我的解决方案如下所示:

fetch('http://localhost:3000/hello')
.then(dataWrappedByPromise => dataWrappedByPromise.json())
.then(data => {
    // you can access your data here
    console.log(data)
})

这里,dataWrappedByPromise是一个Promise例子。要访问Promise实例中的数据,我发现我只需要使用该方法解开该实例。.json()

希望有帮助!

于 2018-01-02T21:05:53.713 回答
5

这个例子是有反应的,但在大多数情况下它应该是一样的。

用您的 url替换this.props.url 以使其适用于大多数其他框架。

解析res.json() 会返回 [[promiseValue]] 但是,如果您随后将其返回到下面的另一个.then()方法,则可以将其作为总数组返回。

let results = fetch(this.props.url)
        .then((res) => {
            return res.json();
        })
        .then((data) => {
            return data;
        })
于 2018-03-05T05:09:48.763 回答
0

阅读手册页,我们可以看到:

then()按照设计,如果不调用方法,就无法从代码同步检查 Promise 的即时状态和值。

为了帮助调试,只有在手动检查 Promise 对象时,您才能看到更多信息作为代码无法访问的特殊属性(目前,这是通过随机化属性名称来实现的,因为缺乏更复杂的语言或调试器支持)。

强调我的。因此,你想做的事是做不到的。更好的问题是为什么你需要像这样访问承诺状态?

于 2015-03-07T16:15:21.377 回答
0

尝试使用await

代替

var value = definitions.PromiseValue 

利用

var value =  await definiton;

这可能会通过产生承诺值来解决您的目的。

注意await 只能在异步函数内部使用,它是 ES2016 的特性。

于 2019-07-02T07:00:00.093 回答
-1

我认为这会很顺利。

(async () => {
  let getDefinitions = await ( () => {
    return new Promise( (resolve, reject) => {
      resolve(ContactManager.request("definition:entities"));
    });
  })();
)();
于 2016-12-31T14:31:28.633 回答
-4

对于返回的响应是 HTML,而不是 JSON 的情况

fetch('http://localhost:3000/hello')
  .then(response => response.text())
  .then(data => {
    // you can see your PromiseValue data here
    console.log(data)
  })
于 2019-04-23T20:10:39.883 回答