How to get value from async function all?
ppedziwiatr opened this issue · comments
just_ppe commented
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.
Tyler Cummings-Bond commented
+1, I'm also stuck on this.
Jens Alfke commented
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
}
}
}