如何在Golang中运行JavaScript

作者:kingname 时间:2022-11-03 14:50:48 

我们知道,在 Python 里面,如果你要运行一段 JavaScript,你可以使用execJS这种第三方库。那么在 Golang 里面,你想运行 JavaScript 的时候又应该怎么办呢?

最近我发现一个使用 Golang 开发的 JavaScript 引擎:Goja[1]。它实现了ES 5.1的所有语法和大部分的ES 6语法,比 Python 的execJS要厉害得多。在一定程度上和特定场景下,它可以完全替代Chrome 的 V8引擎。

我们来看看如使用它运行一段 JavaScript 代码。首先,我来写一段递归版的 JavaScript 代码计算斐波那契数列:

function fib(n) {
    if (n === 1 || n === 2) {
        return 1 
    }
    return fib(n - 1) + fib(n - 2)
}

直接在浏览器上面运行的效果如下:

如何在Golang中运行JavaScript

现在,我们来安装这个Goja:

go get github.com/dop251/goja

接下来我们在 Go 中运行 js 代码:

package main

import (
    "fmt"

    "github.com/dop251/goja"
)

func main() {

    const script = `
    function fib(n) {
        if (n === 1 || n === 2) {
            return 1 
        }
        return fib(n - 1) + fib(n - 2)
    }
    `
    vm := goja.New()
    _, err := vm.RunString(script)
    if err != nil {
        fmt.Println("JS代码有问题!")
        return
    }
    var fn func(int32) int32
    err = vm.ExportTo(vm.Get("fib"), &fn)
    if err != nil {
        fmt.Println("Js函数映射到 Go 函数失败!")
        return
    }
    fmt.Println("斐波那契数列第30项的值为:", fn(30))
}

运行效果如下图所示:

如何在Golang中运行JavaScript

我们来解释一下上面代码的意思。请大家关注截图中的代码行号。第19行,我们创建了一个 JavaScript 的虚拟机。然后在第20行,把这个函数加载到了虚拟机当中。

第25行,我们创建了一个变量,这个变量是函数类型,这个函数接收一个 int32作为参数,并返回另一个int32类型的数据。

第26行,我们把 Golang 里面的这个函数变量与 JavaScript 里面的函数fib关联起来,这样我们就能直接写 Go 代码来调用 JavaScript 代码了。

第31行,我们像调用普通的 Go 函数一样传入参数,然后获得结果。

有一些同学在做爬虫的时候,需要运行一段 JavaScript 代码来生成一段 token,那你不妨试一试Goja,它的速度肯定要比你用Python 版本的快很多。

参考文献

[1] Goja: https://github.com/dop251/goja

来源:https://mp.weixin.qq.com/s/edEee9qsdQZrCPZIgJiEGQ

标签:golang,运行,js
0
投稿

猜你喜欢

  • 常用的C语言排序算法(两种)

    2022-12-28 02:28:37
  • Android如何使用GestureDetector进行手势检测详解

    2022-03-21 22:08:46
  • Java中通过jsch来连接远程服务器执行linux命令

    2023-02-02 22:21:52
  • 浅谈Java转义符\\\\|

    2022-12-11 16:25:43
  • springboot集成springCloud中gateway时启动报错的解决

    2021-09-05 09:51:34
  • java处理数据库不支持的emoji表情符问题解决

    2021-08-21 00:16:58
  • 使用java实现http多线程断点下载文件(一)

    2023-11-23 15:45:51
  • 关于Future机制原理及解析

    2022-01-23 03:57:48
  • C#读写文件的方法汇总

    2022-03-01 04:41:41
  • Flutter应用框架搭建实现屏幕适配方案详解

    2023-09-19 08:16:27
  • Java设计模式之模板方法模式详解

    2021-08-04 04:32:51
  • Spring框架构造注入type属性实例详解

    2021-10-04 19:45:19
  • C#如何给PDF文件添加水印

    2021-07-20 14:32:36
  • Mybatis如何通过接口实现sql执行原理解析

    2022-11-30 11:31:26
  • C#多线程之线程池(ThreadPool)

    2022-05-02 07:12:15
  • Android开发实现的ViewPager引导页功能(动态加载指示器)详解

    2021-10-16 17:40:35
  • unity实现UI元素跟随3D物体

    2021-11-15 02:00:48
  • Chrome Visual Studio 2005下的编译过程

    2022-06-06 02:54:23
  • Maven的porfile与SpringBoot的profile结合使用案例详解

    2023-11-14 00:07:59
  • Mybatis如何解决sql中like通配符模糊匹配问题

    2023-12-22 19:39:52
  • asp之家 软件编程 m.aspxhome.com