简体   繁体   English

有没有办法在不恢复调试器的情况下评估 nodejs 中的承诺?

[英]Is there a way to evaluate promise in nodejs without resuming debugger?

If I type debugger and I want to check something.如果我输入 debugger 并且我想检查一些东西。 But call to that function returns a promise, then i am stuck.但是对该函数的调用返回了一个承诺,然后我被卡住了。

For example:例如:

I typed debugger and it stopped.我输入调试器,然后它停止了。

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

But if I type但是如果我输入

let d = db.User.create(); 

I'll get我去拿

Promise { pending }

now there is no recourse.现在没有办法了。 I can't simply evaluate promise.我不能简单地评估承诺。 Kinda make whole debugger less useful.有点让整个调试器变得不那么有用了。

This would have been no problem, if it was synchronous, I'd have been able to jump in mid program, check out few things and modify program to my liking then run rest of the program.这本来没问题,如果它是同步的,我就可以在程序中间跳转,检查一些东西并根据自己的喜好修改程序,然后运行程序的其余部分。

Probably in order to understand why promises can't be resolved while debugger is paused, you need to understand how Event Loop works.可能为了理解为什么在调试器暂停时无法解决承诺,您需要了解事件循环的工作原理。 There are plenty of resources about it so no need to explain it here.关于它的资源很多,所以不需要在这里解释。

When you pause a Debugger , Event Loop gets paused too.当您暂停Debugger时,事件循环也会暂停。 And everything asynchronous is scheduled and handled in Event Loop .所有异步的事情都在Event Loop中安排和处理。

Possible ways to resolve promise in debugger:在调试器中解决承诺的可能方法:

  • Somehow execute promise synchronously by pooling it manually.以某种方式通过手动合并来同步执行承诺。 But as far as I checked, there is no way to do that.但据我检查,没有办法做到这一点。 V8 doesn't give us that level of control. V8没有给我们那种级别的控制。 But maybe it can be achieved by writing Native Addon .但也许可以通过编写Native Addon来实现。 Perhaps a function that accepts a promise and resolves it using V8 's internals synchronously.也许是一个接受承诺并使用V8的内部同步解决它的函数。
  • Create a new Web Worker or another process and execute the promise there.创建一个新的Web Worker或其他进程并在那里执行承诺。 But you'd have to serialize the data and possibly recreate the state.但是您必须序列化数据并可能重新创建状态。 Though it won't work anyways since creating and passing messages to new "thread" is asynchronous, so...虽然它无论如何都不会工作,因为创建消息并将消息传递给新的“线程”是异步的,所以......

Unfortunately at the moment best and simplest ways I am aware of are:不幸的是,目前我知道的最好和最简单的方法是:

  1. Print current state and use it to construct and execute code outside of the debugger.打印当前状态并使用它在调试器外部构造和执行代码。
  2. Assign result to a variable and continue(F5) debugger, so that your promise can be resolved.将结果分配给变量并继续 (F5)调试器,以便您的承诺得到解决。 After use it as you'd like:随心所欲地使用后:
db.User.create().then(x => global.a = x);
// use global.a as you'd like:
console.log(global.a);

Use the debugger at the either event of the promise being resolved or rejected.在 promise 被解决或被拒绝的任一事件中使用调试器。

function test(db) {

   let d = db.User.create(); 

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


}

Chrome not too long ago launched async debugging in their Chrome Devtools. Chrome 不久前在其 Chrome Devtools 中启动了async调试。 You need to enable the flag in chrome to use it for now.您需要在 chrome 中启用该标志才能暂时使用它。

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

Please refer https://gist.github.com/martinheidegger/4c2b7908005f65f9a53b25d5fec65f63 check debug-promise.js module请参考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(() => {})
//   
//   ---
//
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)}

Or more basically或者更基本的

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

That's how you resolve promises.这就是你解决承诺的方式。 Don't forget to add the catch or you will have some trouble.不要忘记添加捕获,否则你会遇到一些麻烦。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM