Repository navigation
Promise eval in repl yields inaccessible object #18905
Description
Activity
- addedreplIssues and PRs related to the REPL subsystem.Issues and PRs related to the REPL subsystem.questionIssues asking questions about Node.js.Issues asking questions about Node.js.and removedquestionIssues asking questions about Node.js.Issues asking questions about Node.js.
on Feb 21, 2018 foo()returns promise inres = foo()expression and therefore,resis a promise instance.
{ success: true }its just a REPL output expression which is specifically handled(with custom eval function) for promise instance.> res = foo() { success: true } > res <- this should return { success: true } (from custom eval) { success: true }
What you need is something like
res = await foo();which will be available in the future release.Closing this ticket, feel free to reopen it.
@princejwesley I see, thanks for the heads up. It does seem a bit confusing though. I mean, if
resis actually a Promise instance then why is the repl output showing{ success: true }? Why doesn't it show the actual value that it holds?Well, I ended up figuring it out anyway. I'm now able to get the "real" promise.then result assigned to the variable, so the repl feels synchronous and provides a much nicer experience.
@tomas Your custom eval function (
myEval) handlesPromise.thenand emits{ success: true }as output to terminal.Is that a question? You can look at my original custom eval function in the OP.
The one I'm using now is way more complex.
@tomas No, its not a question. Just trying to clear the doubt part. Your custom eval function runs the expression in a given context (
resis still promise instance) and decides how to emit the resulting value(res) in the terminal.OK. I still don't see the point why it works like this. Shouldn't what you see be what you get?
> res = foo() // res is set to calling foo which returns an unresolved promise // `res = foo()` returns the promise as well, which is then handled with: // res.then(function(val) { // cb(null, val) // ... // which then calls back with the resolve value of the promise as the return value { success: true } // however res is still set to the promise result of foo(), nothing has changed that yet
what you want is to parse the expression and perform an assignment to the variable like
res.then(function(val) { eval(`${variable} = val`); cb(null, val) ...
in #15566 we use acorn (a javascript syntax parser/lexer/tokenizer) to split the assignment, you can do something similar
@devsnek Thanks for a clearer explanation. The eval trick is actually what I'm doing now.
// however res is still set to the promise result of foo(), nothing has changed that yet
That's precisely my point. If
resis still the result offoo()(the unresolved promise), then why does the repl show the result of the promised function when inspecting it? It should output something likePromise { ... }, don't you think?no, you call the callback with the resolved value (
{ success: true }) not the return value of the evaluated expression (Promise { <pending> })Ok, thanks, and sorry for the confusion. :)
I'm trying to build a custom repl that yields promises before returning the value to the user, but for some reason I'm unable to "reach" the final value, even though it does appear to be correctly assigned.
This is the code I'm using:
And this is what happens:
However, the "real" result does get correctly assigned to
_:Is there something I'm missing?
Thanks!