Otto是用Go实现的Javascript 解析执行库(https://github.com/robertkrimen/otto),没有使用native代码例如v8.
1. Go调用js
直接执行一段js,返回结果:
package main import ( "fmt" "github.com/robertkrimen/otto" ) func main() { vm := otto.New() v, err := vm.Run(` var a = 1 a++ a `) if v.IsNumber() { i, _ := v.ToInteger() fmt.Println("result is", i) // result is 2 } else if err != nil { fmt.Println("there's error:", err) } }
先执行一段js 定义function,然后调用它:
func main() { vm := otto.New() _, err := vm.Run(` function foo() { var a = 1 a++ return a } `) if err != nil { panic("define js function error: " + err.Error()) } vf, _ := vm.Get("foo") if !vf.IsFunction() { panic("'foo' is not a function") } v, err := vf.Call(otto.Value{}) // 第一个参数是this if err != nil { fmt.Println("call foo() error:", err) } else { fmt.Println("foo() returns:", v) // foo() returns: 2 } }
vm代表一个js runtime,可以直接get/set顶层对象。vm.Run先在runtime设置名为“foo”的函数,然后vm.Get获取该函数对象,最后调用它。
2. js调用Go
用Go定义一个foo函数,然后在js里调用:
func main() { vm := otto.New() err := vm.Set("foo", func (call otto.FunctionCall) otto.Value { a := 1 a++ v, _ := otto.ToValue(a) return v }) if err != nil { panic("define foo func error: " + err.Error()) } _, err = vm.Run(` console.log("foo()=" + foo()) // foo()=2 `) if err != nil { panic("injs call foo() error: " + err.Error()) } }
otto.FunctionCall代表js->go调用(可用来获取传参)。
下面是一个比较实际并复杂些的例子:在Go定义一个函数按id查询公司详情,在js里调用:
package main import ( "database/sql" "github.com/robertkrimen/otto" _ "github.com/ziutek/mymysql/godrv" ) func main() { // CREATE TABLE IF NOT EXISTS comp (id BIGINT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(64) NOT NULL UNIQUE, create_time DATETIME NOT NULL); // INSERT INTO comp (name, create_time) VALUES ('comp-1', now()); // INSERT INTO comp (name, create_time) VALUES ('comp-2', now()); db, err := sql.Open("mymysql", "tcp:127.0.0.1:3306*testdb/root/1") if err != nil { panic(err) } defer db.Close() vm := otto.New() // comp(id/number) {id/number, name/string, create_time/number} // Panics. err = vm.Set("comp", func (call otto.FunctionCall) otto.Value { arg0 := call.Argument(0) id, _ := arg0.ToInteger() //(错误处理暂忽略) name := "" create_time := 0 err = db.QueryRow(`SELECT name,UNIX_TIMESTAMP(create_time) FROM comp WHERE id=? `, id).Scan( &name, &create_time) if err == sql.ErrNoRows || err != nil { // 没查到或出错 panic("query error: " + err.Error()) } ma := map[string]interface{} { "id": id, "name": name, "create_time": create_time, } v, err := vm.ToValue(ma) //(otto.ToValue只用于简单对象,map需使用vm) if err != nil { panic("convert result error: " + err.Error()) } return v }) if err != nil { panic("define comp func error: " + err.Error()) } _, err = vm.Run(` var co = comp(1) console.log("comp(1)=" + JSON.stringify(co) ) // comp(1)={"create_time":1554882802,"id":1,"name":"comp-1"} console.log("result type=" + typeof co) // result type=object `) if err != nil { panic("injs call comp() error: " + err.Error()) } }
需要理解一点:otto是纯用Go实现的,所以上面js里执行“JSON.stringify”时,最终实际是Go来stringify这个co对象。可以想象成每个js对象都有对应的Go对象,这当然会在数据传入传出runtime、以及每次方法调用时产生cost. 初步测试表明1w条数据内速度还是挺快的。
用Go编写系统代码,用js编写业务代码(开发敏捷|不需重启),在中小型项目及测试等领域的前景还是值得期待的。
相关推荐
Otto IntelliJ Plugin Plugin to navigate between events posted by Otto. Deprecated! Otto is deprecated in favor of RxJava and RxAndroid. These projects permit the same event-driven programming model as...
"Otto Group Product Classification Challenge" 是一个数据竞赛项目,旨在挑战参赛者对商品进行准确分类的能力。这个压缩包文件包含了用于训练和评估分类算法的数据集。在这个挑战中,重点是运用机器学习技术,特别...
开源项目-trashhalo-otto-web.zip,Js to execute golang webassembly that runs an embedded js interpreter (otto) which calculates fibonacci
在本资源中,我们关注的是一个与数据科学竞赛相关的项目,特别是Kaggle上的 Otto 多目标推荐系统。这个项目的标题表明它是一个源代码集合,实现了某种推荐算法,该算法在Kaggle的 Otto 比赛中取得了相当不错的成绩,...
async-otto-1.0.0.jar
Otto-案例数据集中的train
而"otto-data-redis"则可能是某个项目或库,它将Otto(一个JavaScript运行时环境)与Redis集成,以便在JavaScript环境中利用Redis的强大功能。Otto通常用于在服务器端执行JavaScript代码,例如在Google V8引擎之外的...
40.[开源][安卓]otto-master
资源分类:Python库 所属语言:Python 资源全名:otto_ml-0.1.2-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059
**Otto Tabs-crx插件** 是一款专为提高网页浏览效率而设计的浏览器扩展程序。这款插件针对英语用户,特别关注于帮助用户更好地管理和组织浏览器中的标签页,尤其适用于那些经常处理大量同时打开的网页标签的用户。 ...
标题中的"em算法matlab代码-Otto-Product-Search"指的是一个使用EM(期望最大化)算法的MATLAB实现,该实现可能与Otto集团的产品搜索优化问题有关,这是一个在Kaggle上举办的竞赛。EM算法是一种在统计学中常用的迭代...
**OTTO机器人** OTTO机器人是一款受到广泛关注的开源机器人项目,尤其适合Arduino爱好者进行学习和探索。这款机器人的设计灵感来源于经典的人形机器人形象,它以其独特的造型和可编程性吸引了大量的DIY爱好者和教育...
kaggle-otto-2015 奥托 Kaggle 挑战代码: ://www.kaggle.com/c/otto-group-product-classification-challenge 安装 使用 pip 安装需求: pip install -r requirements.txt 需求包含像 numpy 这样的库,要求在你...
奥托-- import "github.com/robertkrimen/otto" Package otto是一个用Go原生编写JavaScript解析器和解释器。 import ( "github.com/robertkrimen/otto") 在VM中运行内容vm := otto . New ()vm . Run ( ` abc = 2 + 2...
otto-ui 用于规则自动化引擎的Angular 6构建UI。 使用HeadlessChrome在本地运行单元测试$ scripts/run_tests.sh
"github.com/cardigann/go-cloudflare-scraper" ) func main () { scraper , err := scraper . NewTransport ( http . DefaultTransport ) if err != nil { log . Fatal ( err ) } c := ...
兼容性Otto Tabs可与所有支持扩展程序的基于Chrome的浏览器( , , )一起使用。 检查此链接以使用Opera进行安装: : 产品特点这些功能可以打开和关闭。 默认情况下,前两个处于启用状态。自动分组/堆叠标签来自...
Kaggle.com 上的 Otto Group 产品分类挑战赛 入门 用 brew 安装 R brew tap homebrew/science brew install r 安装 RStudio