Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] How to get the Promise result value? #69

Closed
kuoruan opened this issue Jan 29, 2021 · 10 comments · Fixed by #74 or #76
Closed

[feature] How to get the Promise result value? #69

kuoruan opened this issue Jan 29, 2021 · 10 comments · Fixed by #74 or #76

Comments

@kuoruan
Copy link
Contributor

kuoruan commented Jan 29, 2021

ctx, _ := v8go.NewContext(nil)

val, err := ctx.RunScript(`new Promise((resolve) => setTimeout(() => resolve(1), 1000)).then(console.log)`, "value.js")
if err != nil {
  panic(err)
}

fmt.Printf("result: %s", val.String())
result: [object Promise]

I want to get the Promise result, for the example code is 1

@kuoruan
Copy link
Contributor Author

kuoruan commented Jan 29, 2021

I think this will be possible after merging #68.

@rogchap
Copy link
Owner

rogchap commented Jan 30, 2021

Hey @kuoruan;
This is a bit of a tricky one right now; #68 could help if you create your own callback function to manage the resolved value; but that would be just a workaround.
What we really need is #61 but this has a large scope because the V8 Object class includes arrays, dates, regex, promises as well as regular objects (and more).
Once I have #68 working, I'll move to addressing the Object class (I already have a branch where I made a start)

@fizx
Copy link
Collaborator

fizx commented Jan 31, 2021

I'd like this too, but for simplicity, I don't need complex/useful value types. The following code would be totally fine:

if val.IsPromise() {
	val.PromiseCallback(func(thePromiseResult *v8go.Value, e error) { println(thePromiseResult.String()) })
}

I think I can effectively get there with FunctionTemplates and some ugly code, but also happy to contribute.

@rogchap
Copy link
Owner

rogchap commented Feb 1, 2021

Hey @fizx I'm working on the Object/Promise code right now.
I've not fleshed out the complete API, but it will be something like:

val.AsPromise().Result()

@rogchap rogchap linked a pull request Feb 8, 2021 that will close this issue
@kuoruan
Copy link
Contributor Author

kuoruan commented Feb 10, 2021

Hi @rogchap , I see you added the support for Object, do you have a plan to add Promise?

I'm trying to get Promise result from a promise result with your code:

RtnValue PromiseResult(ValuePtr ptr) {
  LOCAL_OBJECT(ptr);
  RtnValue rtn = {nullptr, nullptr};

  Local<Promise> promise = obj.As<Promise>();

  std::cout << promise->State() << std::endl;

  while (promise->State() == Promise::kPending) {
    iso->RunMicrotasks();
  }

  if (promise->State() != Promise::kFulfilled) {
    rtn.error = ExceptionError(try_catch, iso, local_ctx);
  } else {
    MaybeLocal<Value> result = promise->Result();

    m_value* new_val = new m_value;
    new_val->iso = iso;
    new_val->ctx.Reset(iso, local_ctx);
    new_val->ptr.Reset(iso, Persistent<Value>(iso, result.ToLocalChecked()));

    rtn.value = static_cast<ValuePtr>(new_val);
  }

  return rtn;
}

If I run code like Promise.resolve(1), I can get the result.

But code like new Promise(resolve => setTimeout(function() { resolve(1) }, 1000)) the state is always Promise::kRejected

Any thing I'm wrong?

@rogchap
Copy link
Owner

rogchap commented Feb 10, 2021

Hey @kuoruan

Yes, I am working on full support for Promise API as I can imagine people wanting to be able to do thinks like the fetch API etc; #74 Was just a prerequisite.

You seem to be on the right track to get the Promise Result, I know that iso.RunMicrotasks() API no longer exists so you might want to try iso.PerformMicrotaskCheckpoint() instead.

@rogchap
Copy link
Owner

rogchap commented Feb 11, 2021

@kuoruan I've noticed another error: setTimeout is not part of ECMA-262 and therefore not implemented in V8 😱
You'll need to implement that yourself with a Function Template and setting the global object via the Object Template and creating a new Context. This is why you are getting kRejected

@kuoruan
Copy link
Contributor Author

kuoruan commented Feb 18, 2021

Hi @rogchap
Seems v8 already has setTimeout function. https://stackoverflow.com/a/60355125/5266411

I tried this:

$ brew install v8
$ d8 -v
V8 version 8.8.278.15

create a new file like:

console.log("a");
setTimeout(() => {
    console.log("c");
}, 5000);
console.log("b");
d8 example.js

no error found.

@kuoruan
Copy link
Contributor Author

kuoruan commented Feb 18, 2021

OK, there is only setTimeout but no clearTimeout in d8.

https://github.com/v8/v8/blob/b38bf5b0b1f149f7af3fd90a2ce12344e7191d03/src/d8/d8.cc#L2443-L2444

@rogchap
Copy link
Owner

rogchap commented Feb 18, 2021

d8 is different from v8; d8 implements setTimeout for debugging v8. d8 is an example of a CLI tool that uses v8, just like any program that uses v8go would also.

@kuoruan kuoruan changed the title How to get then Promise result value? [feature] How to get the Promise result value? Feb 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants