`
pelli
  • 浏览: 6193 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Go otto 介绍 - basic

    博客分类:
  • Go
 
阅读更多

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编写业务代码(开发敏捷|不需重启),在中小型项目及测试等领域的前景还是值得期待的。

分享到:
评论

相关推荐

    Android代码-otto-intellij-plugin

    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.zip

    "Otto Group Product Classification Challenge" 是一个数据竞赛项目,旨在挑战参赛者对商品进行准确分类的能力。这个压缩包文件包含了用于训练和评估分类算法的数据集。在这个挑战中,重点是运用机器学习技术,特别...

    开源项目-trashhalo-otto-web.zip

    开源项目-trashhalo-otto-web.zip,Js to execute golang webassembly that runs an embedded js interpreter (otto) which calculates fibonacci

    kaggle比赛—otto多目标推荐系统源代码,单模型分数0.594,LB排名30左右.zip

    在本资源中,我们关注的是一个与数据科学竞赛相关的项目,特别是Kaggle上的 Otto 多目标推荐系统。这个项目的标题表明它是一个源代码集合,实现了某种推荐算法,该算法在Kaggle的 Otto 比赛中取得了相当不错的成绩,...

    async-otto-1.0.0.jar

    async-otto-1.0.0.jar

    Otto-案例数据集中的train

    Otto-案例数据集中的train

    otto-data-redis:Redis中Otto的数据存储

    而"otto-data-redis"则可能是某个项目或库,它将Otto(一个JavaScript运行时环境)与Redis集成,以便在JavaScript环境中利用Redis的强大功能。Otto通常用于在服务器端执行JavaScript代码,例如在Google V8引擎之外的...

    40.[开源][安卓]otto-master

    40.[开源][安卓]otto-master

    Python库 | otto_ml-0.1.2-py3-none-any.whl

    资源分类:Python库 所属语言:Python 资源全名:otto_ml-0.1.2-py3-none-any.whl 资源来源:官方 安装方法:https://lanzao.blog.csdn.net/article/details/101784059

    Otto Tabs-crx插件

    **Otto Tabs-crx插件** 是一款专为提高网页浏览效率而设计的浏览器扩展程序。这款插件针对英语用户,特别关注于帮助用户更好地管理和组织浏览器中的标签页,尤其适用于那些经常处理大量同时打开的网页标签的用户。 ...

    em算法matlab代码-Otto-Product-Search:https://www.kaggle.com/c/otto-group-pr

    标题中的"em算法matlab代码-Otto-Product-Search"指的是一个使用EM(期望最大化)算法的MATLAB实现,该实现可能与Otto集团的产品搜索优化问题有关,这是一个在Kaggle上举办的竞赛。EM算法是一种在统计学中常用的迭代...

    OTTO机器人资料以及3D打印图纸

    **OTTO机器人** OTTO机器人是一款受到广泛关注的开源机器人项目,尤其适合Arduino爱好者进行学习和探索。这款机器人的设计灵感来源于经典的人形机器人形象,它以其独特的造型和可编程性吸引了大量的DIY爱好者和教育...

    kaggle-otto-2015:奥托 Kaggle 挑战代码

    kaggle-otto-2015 奥托 Kaggle 挑战代码: ://www.kaggle.com/c/otto-group-product-classification-challenge 安装 使用 pip 安装需求: pip install -r requirements.txt 需求包含像 numpy 这样的库,要求在你...

    otto:Go(golang)中JavaScript解释器

    奥托-- 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:otto-engine的Web UI

    otto-ui 用于规则自动化引擎的Angular 6构建UI。 使用HeadlessChrome在本地运行单元测试$ scripts/run_tests.sh

    go-cloudflare-scraper:使用Otto解决Cloudflare挑战的golang http.Transport层

    "github.com/cardigann/go-cloudflare-scraper" ) func main () { scraper , err := scraper . NewTransport ( http . DefaultTransport ) if err != nil { log . Fatal ( err ) } c := ...

    chrome-otto-tabs:智能标签管理

    兼容性Otto Tabs可与所有支持扩展程序的基于Chrome的浏览器( , , )一起使用。 检查此链接以使用Opera进行安装: : 产品特点这些功能可以打开和关闭。 默认情况下,前两个处于启用状态。自动分组/堆叠标签来自...

    kaggle-otto-group-product-classification-challenge:Otto Group 产品分类挑战

    Kaggle.com 上的 Otto Group 产品分类挑战赛 入门 用 brew 安装 R brew tap homebrew/science brew install r 安装 RStudio

Global site tag (gtag.js) - Google Analytics