Bri*_*ica 6 javascript go webassembly
我试过
js.Global().Call("throw", "yeet")
Run Code Online (Sandbox Code Playgroud)
但回来了
恐慌:1:1:预期的操作数,找到“类型”[恢复] wasm_exec.f7bab17184626fa7f3ebe6c157d4026825842d39bfae444ef945e60ec7d3b0f1.js:51恐慌:syscall / js:Value.Call:属性抛出不是函数,未定义
我看到Error
中定义了一个类型syscall/js
,但没有什么可以抛出它https://golang.org/pkg/syscall/js/#Error
throw
WebAssembly不可能出现JS 错误。在 JS 中,当您throw
输入值时,JS 运行时会将堆栈展开到最近的try
块,或记录未捕获的错误。WASM 执行是在独立的执行环境中的隔离沙箱中执行的,无法直接访问 JS 堆栈。来自 WASM文档:
每个 WebAssembly 模块都在使用故障隔离技术与主机运行时分离的沙盒环境中执行。
如果 WASM 调用抛出异常的 JS 代码,该错误将被 WASM 运行时捕获并进行处理,就好像 WASM 代码发生了恐慌一样。WASM 可以访问trap,但这些陷阱旨在在运行时级别立即停止执行(并且未在 Go 的syscall/js
模块中实现)。
表示可能失败的代码执行的惯用方法是返回 a Promise
,然后返回resolve
成功时的承诺或reject
失败时的承诺。调用 JS 代码可以等待块内的 Promise 执行try/catch
并处理其中的错误,或者使用 Promise 链并在.catch()
回调中处理错误。这是一个简短的例子:
func main() {
c := make(chan struct{})
js.Global().Set("doSomething", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
handler := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
resolve := args[0]
reject := args[1]
go func() {
data, err := doSomeWork()
if err != nil {
// err should be an instance of `error`, eg `errors.New("some error")`
errorConstructor := js.Global().Get("Error")
errorObject := errorConstructor.New(err.Error())
reject.Invoke(errorObject)
} else {
resolve.Invoke(js.ValueOf(data))
}
}()
return nil
})
promiseConstructor := js.Global().Get("Promise")
return promiseConstructor.New(handler)
})
<-c
}
Run Code Online (Sandbox Code Playgroud)
然后,在你的 JS 代码中:
(async () => {
try {
await window.doSomething();
} catch (err) {
console.log('caught error from WASM:', err);
}
}();
Run Code Online (Sandbox Code Playgroud)
或者
window.doSomething()
.then(_ => /* ... */)
.catch(err => {
console.log('caught error from WASM:', err);
});
Run Code Online (Sandbox Code Playgroud)
我不同意@superhawk610 的观点
\n\n\n不可能从 WebAssembly 抛出 JS 错误
\n
好吧,你可以扔它,但它有多实用呢?根据浏览器的不同,您甚至可能会获得一些可读的堆栈跟踪,但大多数情况下,解释一些像@superhawk610Promise
这样的逻辑会更有意义。但是,如果您真的不想抛出异常,这里是一个简单的例子。
1. 可以提供 throw 函数存根
\n// Throw function stub to throw javascript exceptions\n// Without func body!\nfunc Throw(exception string, message string)\n
Run Code Online (Sandbox Code Playgroud)\n2. 然后通过创建 yourpkg_js.s 文件为汇编器提供提示
\n// Throw enables to throw javascript exceptions\nTEXT \xc2\xb7Throw(SB), NOSPLIT, $0\n CallImport\n RET\n
Run Code Online (Sandbox Code Playgroud)\n3. 通过扩展 wasm_exec / 你的 wasm importObject 添加 js 回调
\n// Throw enables to throw javascript exceptions\nTEXT \xc2\xb7Throw(SB), NOSPLIT, $0\n CallImport\n RET\n
Run Code Online (Sandbox Code Playgroud)\n然后您可以通过提供Error
类名和消息来抛出错误。例如
this.importObject = {\n go: {\n // ...\n\n // func Throw(exception string, message string)\n \'<your-pkg-import-path>.Throw\': (sp) => {\n const exception = loadString(sp + 8)\n const message = loadString(sp + 24)\n const throwable = globalThis[exception](message)\n throw throwable\n }\n }\n}\n
Run Code Online (Sandbox Code Playgroud)\n
归档时间: |
|
查看次数: |
1595 次 |
最近记录: |