Skip to content

How to await a Promise to resolve or reject? #694

@movsb

Description

@movsb

I was trying to provide some go function like http.Get to be used in js by using Promise, the problem is that the main loop exited immediately without waiting for the promise to fulfill.

A minimal snippet:

package main

import (
	"log"
	"net/http"

	"github.com/dop251/goja"
	"github.com/dop251/goja_nodejs/eventloop"
)

func get(args goja.FunctionCall, vm *goja.Runtime) goja.Value {
	promise, resolve, reject := vm.NewPromise()
	ev := vm.Get(`__ev`).Export().(*eventloop.EventLoop)

	go func() {
		log.Println(`before get`)
		rsp, err := http.Get(`http://example.com`)
		log.Println(`after get`)
		if err != nil {
			ev.RunOnLoop(func(vm *goja.Runtime) {
				reject(vm.ToValue(err))
			})
			return
		}
		ev.RunOnLoop(func(vm *goja.Runtime) {
			resolve(vm.ToValue(rsp))
		})
	}()

	return vm.ToValue(promise)
}

func main() {
	ev := eventloop.NewEventLoop()
	ev.Run(func(vm *goja.Runtime) {
		vm.Set(`__ev`, ev)
		vm.Set(`get`, get)
	})
	ev.Run(func(vm *goja.Runtime) {
		// cannot `await get` here, because await cannot be used outside
		// an async function, hence syntax error.
		// SyntaxError: SyntaxError: (anonymous): Line 1:7 Unexpected identifier
		p, _ := vm.RunString(`get('http://example.com')`)
		log.Println(p.Export().(*goja.Promise).State())
	})
	ev.Run(func(r *goja.Runtime) {

	})
}

The go main() exited before before get log can be printed.

How can I wait for the Promise to fulfill?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions