双括号在javascript中是什么意思以及如何访问它们

IT技术 javascript promise es6-promise
2021-01-18 08:06:58

情况

我有以下使用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]].

6个回答

里面是什么东西 [[]]

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

这是内部财产。您无法直接访问它。本机Promise可能只能then与Promise一起或异步展开- 请参阅如何从异步调用返回响应引用规范:

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

你不能

说真的 - 它们是什么?

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

不要告诉任何人,但这些确实是私人符号它们存在的原因是其他内部方法能够访问[[PromiseValue]]. 例如,当 io.js 决定返回Promise而不是接受回调时 - 这将允许它在保证的情况下快速访问这些属性。它们不会暴露在外面。

我可以访问它们吗?

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

那么如何获得我的value呢?

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

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

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

尽管如果我不得不猜测 - 您没有正确地开始转换 API,因为这种转换仅在该方法是同步的(在这种情况下不返回Promise)或它已经返回一个Promise的情况下才有效,这将使它已解决(这意味着您根本不需要转换 - 只需return.

@Benjamin,您的意思是内部插槽和内部方法是由 JS 引擎根据规范实现的吗?我读了一个答案,上面说,它们只是文字,没有实现。(可能是我在这里误解了)另外,我不是在Promise的背景下提问,因为我现在对此没有太多想法。只是问一般像 [[PUT]] [[Prototype]] 等
2021-03-14 08:06:58
@Number945 通常,[[PromiseValue]]在 devtools 中实际上是由 devtools 生成的 - 当您在控制台上按 Enter 键时,它会执行 a evaluateOnCallFrame,将消息发送到 V8,V8 返回子类型的 RemoteObject promise对此有明确的临时支持。上面的答案是正确的(检查员从那里获取这些属性)但不准确(这不是他们到达那里的方式 - 他们通过显式调试器支持到达那里)
2021-03-17 08:06:58
如果Promise被拒绝,那么这些值将通过.catch((values) => {})而不是在.then(() => {})
2021-03-31 08:06:58
另外应该说,它完全违背了 aPromise访问它在 之外的包装值的目的thena 的目的Promise是从非阻塞函数的缺失返回值中抽象出来,即 aPromise表示“未来值”。一旦暴露了这个“未来值”(在 之外then),这些抽象将在整个计算中立即丢失。
2021-04-05 08:06:58

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

我的解决方案如下所示:

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

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

希望有帮助!

@IAM_AL_X 呵呵。我也无法理解我的评论。两年后我唯一能想到的是我打算参考“console.log”行并且完全打错了。确实.then(data => { console.log(data)})可以简化为,.then(console.log)但您绝对正确的是,需要该函数来访问该函数上的常量。抱歉有任何混淆
2021-03-27 08:06:58
@jymbob 我无法理解您的评论。你说在 cafemike 定义了一个箭头函数的地方,那个定义可以用一个常量代替;具体来说,你说他的“then()”相当于“then(resp.json())”。首先,“resp”从何而来?更重要的是,参数“resp.json()”会立即执行,因此传递给“.then()”的参数是任何常量(字符串、对象或数字)在promise仍未解析时执行的结果。也许你不明白“.then()”需要一个函数作为它的参数。
2021-04-04 08:06:58
因为柯里化then(dataWrappedByPromise => dataWrappedByPromise.json())===then(resp.json())
2021-04-06 08:06:58

这个例子是用 react 但在大多数情况下它应该是相同的。

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

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

let results = fetch(this.props.url)
        .then((res) => {
            return res.json();
        })
        .then((data) => {
            return data;
        })

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

按照设计,在不调用then()方法的情况下,无法从代码中同步检查Promise的即时状态和值

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

强调我的。因此,您想做的事情无法完成。更好的问题是为什么你需要像那样访问 promise 状态?

尝试使用await

代替

var value = definitions.PromiseValue 

利用

var value =  await definiton;

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

请注意, await 只能在异步函数中使用,并且它是 ES2016 的一个特性。

你能解释一下这是如何解决目的的吗?谢谢!
2021-04-06 08:06:58