有没有办法在不重新启动调试器的情况下评估nodejs中的promise?

时间:2018-03-03 08:24:50

标签: javascript node.js promise

如果我输入调试器,我想检查一下。但是对该函数的调用会返回一个承诺,然后我就被卡住了。

例如:

我键入了调试器并停止了。

function test(db) {
    debugger;
    // here i want to see something
    var a = .....;
}

但如果我输入

let d = db.User.create(); 

我会得到

Promise { pending }

现在没有追索权。我不能简单地评估承诺。有点使整个调试器不那么有用。

这不会有问题,如果它是同步的,我已经能够跳到程序中期,查看一些东西并根据自己的喜好修改程序然后运行其余的程序。

6 个答案:

答案 0 :(得分:2)

可能是为了理解为什么调试器暂停时无法解决承诺,您需要了解事件循环的工作方式。有很多相关资源,因此无需在此处进行解释。

暂停调试器时,事件循环也将暂停。异步的一切都在事件循环中安排和处理。

在调试器中解决承诺的可能方法:

  • 以某种方式通过手动合并诺言来同步执行诺言。但是据我检查,还没有办法做到。 V8 没有给予我们这种控制水平。但是也许可以通过编写本地插件来实现。也许是一个接受承诺并使用 V8 内部同步地解决它的函数。
  • 创建一个新的 Web Worker 或其他过程,然后在其中执行承诺。但是您必须序列化数据并可能重新创建状态。尽管由于创建和传递消息到新的“线程”是异步的,所以它仍然无法正常工作,所以...

不幸的是,目前我所知道的最好和最简单的方法是:

  1. 打印当前状态,并使用它在调试器之外构造和执行代码。
  2. 将结果分配给变量和 continue(F5)调试器,以便可以兑现您的承诺。使用后,如您所愿:
db.User.create().then(x => global.a = x);
// use global.a as you'd like:
console.log(global.a);

答案 1 :(得分:0)

如果你不想在调试时评估控制台中的promises, 您可以退回到异步等待,并在控制台node inspect和浏览器开发工具版本中获得更愉快和同步的调试体验。

例如: const createUser = async() => ( let d = await db.User.create(); debugger; return d; )

on await你的函数将暂停但是在promise解析时调试器将自动恢复,从而为你提供返回的异步值。

答案 2 :(得分:0)

请参阅https://gist.github.com/martinheidegger/4c2b7908005f65f9a53b25d5fec65f63 检查debug-promise.js模块

'use strict'

var debug = require('./debug-promise')

debug.wrap(() => new Promise(() => {})).then(() => console.log('a executed'))
debug.wrap(() => Promise.resolve('x')).then(() => console.log('b executed'))


//
// This will output something like:
//
//   b executed
//   1 Promise is still unfullfilled!
//   --- (V347P-M6K) ---
//     at Object.<anonymous> (/debug-test2.js:5:7)
//     at Module._compile (module.js:571:32)
//     at Object.Module._extensions..js (module.js:580:10)
//   
//     CODE
//       () => new Promise(() => {})
//   
//   ---
//

答案 3 :(得分:0)

const foo = async(db)=>{//just be sure that you are in async for this one

try{

let d = await db.User.create(); 
//now d is the result
}catch (err) {console.log(err)}

或更简单地

 db.User.create().then((data)=>console.log('user created',data))
                 .catch(err=>console.log('err'));

这就是您兑现承诺的方式。不要忘记添加渔获物,否则会遇到麻烦。

答案 4 :(得分:-1)

不久前,Chrome浏览器在其Chrome Devtools中启动了async调试。您需要启用chrome中的标记才能使用它。

在此处查看这篇不错的文章-https://www.html5rocks.com/en/tutorials/developertools/async-call-stack/

答案 5 :(得分:-2)

在承诺被解决或被拒绝的任何一个事件中使用调试器。

function test(db) {

   let d = db.User.create(); 

   d.then((result) => {
      debugger;
      ...
   },
   (e) => {
      debugger;
      ...
   })


}