golang集成Duktape JavaScript引擎插件库go-duktape的使用
Golang集成Duktape JavaScript引擎插件库go-duktape的使用
Duktape是一个轻量级、可嵌入的JavaScript引擎。go-duktape是Duktape的Go语言绑定库,实现了大部分Duktape API。
安装
这个包完全支持go get,不需要安装任何外部C库。只需执行以下命令安装:
go get gopkg.in/olebedev/go-duktape.v3
基本使用示例
package main
import "fmt"
import "gopkg.in/olebedev/go-duktape.v3"
func main() {
ctx := duktape.New() // 创建新的Duktape上下文
ctx.PevalString(`2 + 3`) // 执行JavaScript表达式
result := ctx.GetNumber(-1) // 从栈顶获取结果
ctx.Pop() // 弹出栈顶元素
fmt.Println("result is:", result)
// 为防止内存泄漏,使用完上下文后记得销毁
ctx.DestroyHeap()
}
Go函数绑定
可以将Go函数绑定到JavaScript上下文中:
package main
import "fmt"
import "gopkg.in/olebedev/go-duktape.v3"
func main() {
ctx := duktape.New()
// 将Go函数绑定为JavaScript全局函数log
ctx.PushGlobalGoFunction("log", func(c *duktape.Context) int {
fmt.Println(c.SafeToString(-1)) // 打印传入的参数
return 0
})
ctx.PevalString(`log('Go lang Go!')`) // 调用绑定的函数
}
运行结果:
$ go run *.go
Go lang Go!
定时器功能
可以注入定时器函数到全局作用域:
package main
import "fmt"
import "gopkg.in/olebedev/go-duktape.v3"
func main() {
ctx := duktape.New()
// 注入setTimeout、setInterval、clearTimeout、clearInterval到全局作用域
ctx.PushTimers()
ch := make(chan string)
ctx.PushGlobalGoFunction("second", func(_ *Context) int {
ch <- "second step"
return 0
})
ctx.PevalString(`
setTimeout(second, 0); // 异步调用
print('first step'); // 同步调用
`)
fmt.Println(<-ch)
}
运行结果:
$ go run *.go
first step
second step
命令行工具
安装命令行工具:
go get gopkg.in/olebedev/go-duktape.v3/...
执行JavaScript文件:
$GOPATH/bin/go-duk file.js
性能对比
引擎 | 执行时间 |
---|---|
otto | 200.13s |
anko | 231.19s |
agora | 149.33s |
GopherLua | 8.39s |
go-duktape | 9.80s |
注意事项
- 该包尚未完全测试,使用时需谨慎
- 使用完上下文后务必调用
DestroyHeap()
防止内存泄漏 - Go和JavaScript上下文之间的绑定功能尚未完全实现
贡献
欢迎提交Pull Request!讨论问题时请提交包含提案和更改的Pull Request。
更多关于golang集成Duktape JavaScript引擎插件库go-duktape的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang集成Duktape JavaScript引擎插件库go-duktape的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用go-duktape在Golang中集成Duktape JavaScript引擎
Duktape是一个轻量级、可嵌入的JavaScript引擎,而go-duktape是它的Golang绑定。下面我将介绍如何在Golang项目中使用go-duktape来执行JavaScript代码。
安装go-duktape
首先需要安装go-duktape库:
go get github.com/olebedev/go-duktape
基本使用示例
package main
import (
"fmt"
"github.com/olebedev/go-duktape"
)
func main() {
// 创建新的Duktape上下文
ctx := duktape.New()
// 执行简单的JavaScript代码
err := ctx.PevalString(`var x = 10; var y = 20; x + y;`)
if err != nil {
fmt.Println("Error:", err)
return
}
// 从栈顶获取结果
result := ctx.GetNumber(-1)
fmt.Println("Result:", result) // 输出: Result: 30
// 弹出结果
ctx.Pop()
// 定义一个Go函数供JavaScript调用
ctx.PushGlobalGoFunction("add", func(c *duktape.Context) int {
a := c.GetNumber(0) // 获取第一个参数
b := c.GetNumber(1) // 获取第二个参数
c.PushNumber(a + b) // 将结果压入栈
return 1 // 返回结果数量
})
// 调用我们定义的函数
ctx.PevalString(`print("10 + 20 =", add(10, 20));`)
// 销毁上下文
ctx.Destroy()
}
高级功能示例
1. 在Go和JavaScript之间传递复杂数据
func jsonExample() {
ctx := duktape.New()
defer ctx.Destroy()
// 定义一个JSON字符串
jsonStr := `{"name": "Alice", "age": 25, "hobbies": ["reading", "swimming"]}`
// 在JavaScript中解析JSON
ctx.PevalString(fmt.Sprintf(`var person = %s;`, jsonStr))
// 从JavaScript中获取属性
ctx.PevalString(`JSON.stringify(person)`)
fmt.Println("Person as JSON:", ctx.GetString(-1))
ctx.Pop()
// 或者直接操作对象
ctx.GetGlobalString("person")
ctx.GetPropString(-1, "name")
fmt.Println("Name:", ctx.GetString(-1))
ctx.Pop2()
}
2. 错误处理
func errorHandling() {
ctx := duktape.New()
defer ctx.Destroy()
// 故意执行有错误的代码
err := ctx.PevalString(`function foo() { bar(); } foo();`)
if err != nil {
// 获取错误堆栈
ctx.GetPropString(-1, "stack")
fmt.Println("Error:", ctx.GetString(-1))
ctx.Pop()
}
}
3. 异步执行JavaScript
func asyncExample() {
ctx := duktape.New()
defer ctx.Destroy()
// 注册setTimeout模拟函数
ctx.PushGlobalGoFunction("setTimeout", func(c *duktape.Context) int {
// 获取回调和延迟时间
delay := c.GetNumber(1)
// 这里只是模拟,实际应该使用goroutine实现真正的异步
fmt.Printf("Will execute after %.0fms\n", delay)
return 0
})
ctx.PevalString(`
setTimeout(function() {
print('This executes later');
}, 1000);
print('This executes first');
`)
}
性能考虑
- Duktape是一个轻量级引擎,适合嵌入式使用,但不适合高性能场景
- 频繁的Go-JavaScript互操作会有性能开销
- 对于复杂应用,考虑将逻辑尽量放在一边(全Go或全JavaScript)
实际应用场景
- 配置文件使用JavaScript编写
- 实现业务规则引擎
- 提供用户脚本扩展功能
- 在Go应用中嵌入JavaScript解释器
总结
go-duktape为Golang提供了简单有效的JavaScript执行能力,适合需要轻量级脚本支持的场景。通过上面的示例,你可以快速上手集成JavaScript功能到你的Go应用中。