在 go 函数中等待 js 异步函数(promise)

Posted

技术标签:

【中文标题】在 go 函数中等待 js 异步函数(promise)【英文标题】:await js async function (promise) inside a go function 【发布时间】:2021-07-16 22:02:23 【问题描述】:

我希望将 indexdb 集成到基于 wasm 的应用程序中。您如何在 go 函数中“等待”来自 js 函数的承诺。这是一个例子

    async getItem(key) 
        try
            const out = await database.getItem(key);
            return out;
        catch(err)
            return null;
        
    

继续前进

func Get(key string)[]byte

    found :=  js.Global().Get("Store").Call('getItem', key )
    // await for found
    // convert js.Value to to []byte
    return nil


异步回调也可以。

LE:一个糟糕的解决方案是创建一个带有无限循环的 go 例程,直到一个 DOM 变量存在,比如 global.solution+ID 被设置。但我认为这是一个糟糕的解决方案

【问题讨论】:

【参考方案1】:

您可以使用Promise 对象中的then 方法等待结果,如下所示:

package main

import (
    "fmt"
    "syscall/js"
)

func main() 
    wait := make(chan interface)
    js.Global().Call("sayHello", 5000).Call("then", js.FuncOf(func(this js.Value, args []js.Value) interface 
        fmt.Println(args[0])
        wait <- nil
        return nil
    ))
    <-wait
    fmt.Println("we're done here")

请注意,我们在 Go 代码中使用了一个通道来实际等待。我们需要这样做,因为 Go 程序在接收来自 javascript 的回调时必须仍在运行。

index.html 文件:

<html>
    <head>
        <meta charset="utf-8"/>
        <script src="wasm_exec.js"></script>
        <script>
            const go = new Go();
            WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject).then((result) => 
                go.run(result.instance);
            );

            function sayHello(time) 
                return new Promise(resolve => 
                    console.log('waiting %dms and resolving', time)
                    setTimeout(() => resolve('hola!'), time)
                )
            
        </script>
    </head>
    <body></body>
</html>

【讨论】:

非常感谢! 你可能想看this answer@algorithmitcus

以上是关于在 go 函数中等待 js 异步函数(promise)的主要内容,如果未能解决你的问题,请参考以下文章

在 Node.js 中等待异步函数返回

Promise.all()函数中的JS“等待仅在异步函数中有效”[重复]

Python爬虫编程思想(106):基于Splash的爬虫--异步处理与go函数

js异步执行原理

等待异步函数完成而不添加回调

如何在节点 js 中正确使用等待/异步与 for 循环