How can I get the resolved promise result?

590 views
Skip to first unread message

Yao Xiao

unread,
Sep 16, 2020, 2:56:36 AM9/16/20
to v8-users
Hi v8-users,

I'm new to v8.

For a "script" that has a call to a sync function that returns an integer, I figured I could do the following to get the result in C++:

v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
int result_int = result->Int32Value(context).FromJust();

I'm wondering if there's a way to get (i.e. make C++ aware of) the return value an async function? I tried to use await but it seems that the script won't compile.

Ben Noordhuis

unread,
Sep 16, 2020, 3:35:10 AM9/16/20
to v8-users
You can attach your own .then and .catch callbacks if the script's
return value is a promise (which is what the return value of an async
function really is):

if (result->IsPromise()) {
Local<Promise> promise = result.As<Promise>();
if (promise->State() == Promise::kPending) {
Local<Function> resolve = Function::New(context,
Resolve).ToLocalChecked();
Local<Function> reject = Function::New(context, Reject).ToLocalChecked();
promise = promise.Then(resolve, reject).ToLocalChecked();
} else {
result = promise->Result(); // note: distinguish between
kFulfilled and kRejected
// ...
}

You'll need to pump the event loop and/or the microtask queue in order
for the promise to resolve.

Apropos the await keyword, that isn't accepted at the top-level scope
(outside an async function) unless you're executing the script as an
ES module and the --harmony_top_level_await flag is set.

Yao Xiao

unread,
Sep 16, 2020, 6:13:33 PM9/16/20
to v8-users
Thanks for the pointer Ben. I encountered another issue while following your suggestion:

For evaluating the script "new Promise(() => {})", I'd expect result->IsPromise() is true. However, in some cases I'm seeing result->IsPromise() is false if some code are executed before.

I don't have a small example as I couldn't pinpoint the issue. But I'll see this issue if I execute the tensorflow.js source code (from https://cdn.jsdelivr.net/npm/@tensorflow/tf...@2.4.0/dist/tf.js) before the promise, in which case I'll see result->IsPromise() is false. However, when I print the status from v8::String::Utf8Value(isolate, result->ToDetailString(context).ToLocalChecked()), it still outputs "#<Promise>". So I'm confused.

It seems that the execution of tensorflow.js is interfering with something, but I'm not sure how to debug. FYI, I *think* the execution of tensorflow.js succeeded, because I saw no compile/run error, and after that I could still compile/run some tensorflow functions, or just compile/run some other toy functions. It's just that a promise is no longer evaluated to be a promise.

Any ideas why this happens?

Ben Noordhuis

unread,
Sep 17, 2020, 3:36:13 AM9/17/20
to v8-users
On Thu, Sep 17, 2020 at 12:13 AM Yao Xiao <yao...@chromium.org> wrote:
>
> Thanks for the pointer Ben. I encountered another issue while following your suggestion:
>
> For evaluating the script "new Promise(() => {})", I'd expect result->IsPromise() is true. However, in some cases I'm seeing result->IsPromise() is false if some code are executed before.
>
> I don't have a small example as I couldn't pinpoint the issue. But I'll see this issue if I execute the tensorflow.js source code (from https://cdn.jsdelivr.net/npm/@tensorflow/tf...@2.4.0/dist/tf.js) before the promise, in which case I'll see result->IsPromise() is false. However, when I print the status from v8::String::Utf8Value(isolate, result->ToDetailString(context).ToLocalChecked()), it still outputs "#<Promise>". So I'm confused.
>
> It seems that the execution of tensorflow.js is interfering with something, but I'm not sure how to debug. FYI, I *think* the execution of tensorflow.js succeeded, because I saw no compile/run error, and after that I could still compile/run some tensorflow functions, or just compile/run some other toy functions. It's just that a promise is no longer evaluated to be a promise.
>
> Any ideas why this happens?

The file you link to seems to have its own custom Promise
implementation, something that the spec allows (search for
'thenables'.)

You can't really detect that except by checking if it's a thenable (an
object with a .then method) and hope for the best.
Reply all
Reply to author
Forward
0 new messages