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

How to get value from async function all? #338

Open
ppedziwiatr opened this issue Aug 20, 2022 · 2 comments
Open

How to get value from async function all? #338

ppedziwiatr opened this issue Aug 20, 2022 · 2 comments

Comments

@ppedziwiatr
Copy link

ppedziwiatr commented Aug 20, 2022

Hey,

assuming this code:

func main() {
	iso := v8.NewIsolate()
	defer iso.Dispose()
	ctx := v8.NewContext(iso)
	defer ctx.Close()

	// TODO: load contract definition from Warp GW
	ctx.RunScript(`
	const handle = async function handle(state, action) {
	  if (action.input.function === "add") {
		state.counter++;
		return { state };
	  }
	}`, "contract.js")

	// TODO: load contract interactions from Warp GW
	ctx.RunScript(`
	let result = await handle({counter: 0}, {caller: 'ppe', input: {function: 'add'}})
	result = await handle(result.state, {caller: 'ppe', input: {function: 'add'}})
	result = await handle(result.state, {caller: 'ppe', input: {function: 'add'}})
`, "interactions.js")

	val, _ := ctx.RunScript("JSON.stringify(result)", "value.js")

	fmt.Printf("contract state: %s", val)
}

how to properly handle a promise and get a value from result?

Ofc. above example without async/await works flawlessly.

@ti2ger92
Copy link

+1, I'm also stuck on this.

@snej
Copy link

snej commented Dec 7, 2022

In Go you have to check if the result value from V8 is a promise; if it is, you check its state. As long as it's still in the unresolved state, you call the context's PerformMicrotaskCheckpoint method to run a bit longer, then recheck the promise state.

func resolvePromise(val *v8.Value, err error) (*v8.Value, error) {
	if err != nil || !val.IsPromise() {
		return val, err
	}
	for {
		switch p, _ := val.AsPromise(); p.State() {
		case v8.Fulfilled:
			return p.Result(), nil
		case v8.Rejected:
			return nil, errors.New(p.Result().DetailString())
		case v8.Pending:
			r.ctx.PerformMicrotaskCheckpoint() // run VM to make progress on the promise
			// go round the loop again...
		default:
			return nil, fmt.Errorf("illegal v8.Promise state %d", p) // unreachable
		}
	}
}

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

No branches or pull requests

3 participants