NodeJS 从 Console 获取 Promise 结果

NodeJS getting Promise result from Console

提问人:webbyweb 提问时间:4/19/2020 最后编辑:Jonathan Hallwebbyweb 更新时间:5/8/2020 访问量:3286

问:

如果我想从我的节点测试控制台获取 Promise 的结果,我该怎么做?

例如。

let promise = new Promise(() => {
  console.log('my promise');
}
promise.then(() => { console.log('resolved') })
// returns a Promise {<pending>}

await promise.then(() => { console.log('resolved') })
// still returns just a Promise

(async () => {
    await promise
})()
// still returns ... just a Promise

最终,我尝试在断点处从我的节点控制台测试 promise 结果(数据库查询),我只是不断返回 Promise。


更新-我想这比我想象的要复杂。因为知道一个人已经能够回答。

我了解如何在常规环境中获得承诺的结果。我说的是在调试 Node 应用程序时在断点处获取结果。要连接到我所指的控制台,请按照以下说明操作: https://medium.com/@paul_irish/debugging-node-js-nightlies-with-chrome-devtools-7c4a1b95ae27

在 DevTools 的控制台中,promise 不断返回 Promise {}。我不知道是否有可能获得承诺的价值,但如果有人知道任何一种方式,请告诉我。

JavaScript 节点.js 调试 承诺 google-chrome-devtools

评论

0赞 Ry- 4/19/2020
没有包装在额外异步函数中的那个不应该给你一个承诺。它应该是值或语法错误。你能展示一下它的截图吗?(此外,在紧要关头,将变量赋值给 with 或 logging with 是很好的。awaitlet x; promise.then(y => { x = y; })promise.then(console.log)
0赞 Ry- 4/19/2020
(这些都假设你的真正承诺曾经解决过,而你的例子则没有。
0赞 webbyweb 4/19/2020
我将 promise 更改为“resolve('my promise')”,但它仍然只返回“Promise {<pending>}”
0赞 Bergi 4/19/2020
究竟什么是“我的节点测试控制台”?您是否正在使用节点 REPL?
0赞 webbyweb 4/19/2020
@Bergi如果你关注这里,它就会告诉你我的意思:medium.com/@paul_irish/......

答:

1赞 Henok Teklu 4/19/2020 #1

创建 Promise 对象时,应使用此语法

var promiseObj = new Promise(executor);

执行器是具有此签名的函数

function(resolutionFunc, rejectionFunc){
    // typically, some asynchronous operation.
} 

当我们回到您的具体示例时,您可以将其定义为

let promise = new Promise( resolve => {
    resolve("my promise")
})

注意我没有添加拒绝功能

然后你可以做

promise.then(value => console.log(value))

您可以在此处找到详细说明

评论

0赞 Hemant Kumar 4/19/2020
您的解释是正确的,因为在这种情况下,promise 会立即得到解决,但是在 Node 控制台和浏览器控制台上有不同的行为。Node 控制台仍然显示 Promise 处于待处理状态,而浏览器控制台显示它已解决。
0赞 webbyweb 4/19/2020
^谢谢。确切地说,我明白,如果我在应用程序或浏览器控制台中使用它,承诺会正常工作。但不是在调试应用程序时(即在断点处)在控制台中,此处显示了如何连接:medium.com/@paul_irish/...
0赞 Ben Aston 4/19/2020 #2

断点的位置很重要,在 Node.js 调试器和浏览器调试器中的行为是相同的。

在下文中,我使用标签来标识断点位置。<b1>

1.  const p1 = new Promise((resolve) => <b1> resolve('result 1'))
2.  <b2>
3.  const p2 = p1.then(() => <b3> 'result 2')
4.  <b4>

at ,将取消声明,因为执行器函数同步运行,并且变量声明过程尚未完成。<b1>p1

At ,将是一个已履行的承诺 (),使用该值进行解析,因为在执行器函数中调用了 resolve。<b2>p1Promise {<fulfilled>: "result 1"}'result 1'

下一个要命中的断点将是 <b4>注意:不是<b3>

at ,将是一个待处理的 promise (),因为该 promise 已配置了尚未有机会运行的 .then 回调在异步微任务上运行,使程序员有机会在执行之前配置承诺链。毕竟,promise 设计为与异步行为一起使用。<b4>p2Promise {<pending>}.then

在下一个可用的微任务上,将在运行回调时命中。的值保持不变。 早已实现,不会改变。的状态保持不变,因为它的配置尚未完成运行。<b3>.then<b3>p1p2p1p2.then

为了观察其已履行状态,您需要向承诺链的扩展添加断点。p2

let p1 = new Promise((resolve) => resolve('result 1'))
const p2 = p1.then(() => 'result 2')
p2.then(() => {
  // here `p2` === `Promise {<resolved>: "result 2"}`
  console.log(p2)
})

评论

0赞 webbyweb 4/19/2020
正如我之前解释的那样。我知道这就是承诺在常规环境中的运作方式。在调试我的 Node 应用程序时,我试图获得 promise 结果的地方是断点。因此,如果您遵循以下环境,我将运行的控制台将在这里:medium.com/@paul_irish/...我刚刚尝试了您的代码,它再次返回“Promise {pending}”
0赞 Ben Aston 4/19/2020
无论是在节点调试器中运行,还是在浏览器中运行,行为都是相同的。断点的位置很重要。正如我上面所说:“请注意,您始终需要将代码保留在回调函数链中。这是因为异步控制流通过这些回调运行。"
1赞 webbyweb 4/21/2020 #3

从评论中,我猜在 JavaScript 中的断点处不可能获得异步调用结果。

如果有人来到这里并希望像我所寻找的那样能够从 Node 控制台 (REPL) 进行数据库查询,我建议您去这里:

https://medium.com/@vemarav/build-rails-like-console-in-nodejs-repl-2459fb5d387b