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

whether async method is supported #41

Open
ghost opened this issue Jul 31, 2020 · 1 comment
Open

whether async method is supported #41

ghost opened this issue Jul 31, 2020 · 1 comment

Comments

@ghost
Copy link

ghost commented Jul 31, 2020

maybe like this (:з」∠)

{
    let username = 'Tom';
    let remoteName = await request(url)
    assert_eq(username, remoteName);
  }
@lujjjh
Copy link
Owner

lujjjh commented Jul 31, 2020

Gates currently only supports synchronized functions. Asynchronous functions still have a long way to go.

However, you can implement a simple Promise, such as:

package main

import (
	"log"
	"time"

	"github.com/gates/gates"
)

// A Promise contains a `done` channel notifying the Promise is resolved,
// and the `value`.
type Promise struct {
	done  chan struct{}
	value gates.Value
}

func NewPromise() *Promise {
	return &Promise{done: make(chan struct{})}
}

func (p *Promise) Resolve(value gates.Value) {
	p.value = value
	close(p.done)
}

// promiseAll waits all the Promises to be resolved, and returns an array
// of their values.
func promiseAll(call gates.FunctionCall) gates.Value {
	args := call.Args()
	values := make([]gates.Value, 0, len(args))
	for _, v := range args {
		if ref, ok := v.(gates.Ref); ok {
			if promise, ok := ref.ToNative().(*Promise); ok {
				<-promise.done
				values = append(values, promise.value)
				continue
			}
		}
		values = append(values, v)
	}
	return gates.NewArray(values)
}

func ping(call gates.FunctionCall) gates.Value {
	var value gates.String
	if err := gates.NewArgumentScanner(call).Scan(&value); err != nil {
		panic(err)
	}
	promise := NewPromise()
	go func() {
		time.Sleep(1 * time.Second)
		promise.Resolve(value)
	}()
	return gates.NewRef(promise)
}

func main() {
	vm := gates.New()

	vm.Global().Set("promise_all", gates.FunctionFunc(promiseAll))
	vm.Global().Set("ping", gates.FunctionFunc(ping))

	log.Println(vm.RunString(`promise_all(ping("foo"), ping("bar"))`))
}

Be careful that gates.Runtime isn't goroutine-safe and avoid to accessing it in another goroutines.

Also, you can implement an eventloop to schedule the jobs. Please refer to the example in goja_nodejs.

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

1 participant