将GO编绎成JavaScript,用GO语言来写前端代码


发布者 kris  发布时间 1413424802902
关键字 JS开源  开源 
GopherJS是一个将GO编绎成JavaScript的开源项目, 下面的描述来自开源项目主页,Github

GopherJS将GO代码编绎成纯的JavaScript代码。它的主要目的是让你有机会使用GO语言来写前端代码。你可以在线玩一玩。 

你可以使用GO优雅的类型系统和编绎时检查系统,因此你有机会发现大量的潜在BUG,并可以更好的进行重构。想像一下你之前要处理多少有关JavaScript遗留的参数问题,因为你不确定会不会还有人在用这些老API。GopherJS会豪无怨言地帮你解决这些问题。你可以放心,这种BUG将不会再出现。

Goroutines


注* Goroutines是Go语言中一种轻量级的并发实现机制;可以理解为轻量级的多线程机制,不同的是Goroutines运行时还可以访问当前上下文。

JavaScript没有并发的概念(除了web workers,但是与Goroutines不同,他们被隔离地太彻底了)。所以,JavaScript中的代码永远不会被阻塞。一个阻塞的调用将会让你的网页停止响应。所以我们使用了一个带参回调来代替。

GopherJS对于这种限制做了大量的工作: 当一个指令被阻塞(比如通信中的一个通道 channel没有好),整个栈就不会被执行(等待所有的函数都被调用过以后),其它goroutine会暂时休息。然后另外一个准备执行的goroutine会恢复运行(与本地变量一起恢复)。这种机制通过一个闭包来实现。


这种机制生成的代码性能非常好,但是还是没有非阻塞系统(基于原生JS回调)的好。这是GopherJS努力去克服的一面。

但是它也有一个优点,外部JavaScript从来不会被阻塞执行,但你可以使用go语法在JS中达到阻塞的效果。


这是一个Go编绎到JavaScript的示例,来自其Playgroud

GO的代码

package main
import (
"fmt"
"github.com/gopherjs/gopherjs/js"
)
func main() {
fmt.Println("Hello, playground")
js.Global.Call("alert", "Hello, JavaScript")
println("Hello, JS console")
}

JavaScript代码

$packages["main"] = (function() {
  var $pkg = {}, fmt = $packages["fmt"], js = $packages["github.com/gopherjs/gopherjs/js"], main;
  main = function() {
    fmt.Println(new ($sliceType($emptyInterface))([new $String("Hello, playground")]));
    $global.alert($externalize("Hello, JavaScript", $String));
    console.log("Hello, JS console");
  };
  $pkg.$run = function($b) {
    $packages["github.com/gopherjs/gopherjs/js"].$init();
    $packages["runtime"].$init();
    $packages["errors"].$init();
    $packages["sync/atomic"].$init();
    $packages["sync"].$init();
    $packages["io"].$init();
    $packages["math"].$init();
    $packages["unicode"].$init();
    $packages["unicode/utf8"].$init();
    $packages["bytes"].$init();
    $packages["syscall"].$init();
    $packages["strings"].$init();
    $packages["time"].$init();
    $packages["os"].$init();
    $packages["strconv"].$init();
    $packages["reflect"].$init();
    $packages["fmt"].$init();
    $pkg.$init();
    main();
  };
  $pkg.$init = function() {
  };
  return $pkg;
})();

引入了非常多的预定义packages和对象如($global, $String)等,个人认为这样的前端代码实用性并不强,冗余非常明显,降低了可维护。 

目前GO的编绎系统检查地非常严格,不允许一些未定义的外部全局变量的直接访问,如你得这样访问document:

JS代码: 

document.write("Hello world!");

GO代码:

js.Global.Get("document").Call("write", "Hello world!")


这种机制造成了与外部第三方插件(如jQuery)等配合起来非常不便。要写很多额外代码。 实用性比目前的CoffeeScript和TypeScript还要差很多。


 相关阅读





回复 (7)
  • #
  • #1 zkwap 1413452900394

    老外真是闲的蛋疼

  • #2 ChanneW 1413471841882

    一个长处是并发,一个纯粹是单线程, 确实是够蛋疼的.

  • #3 莫兆召 1413508540917

    何苦呢

  • #4 fuadam1982 1413516867574

    @ChanneW #1

    go也是单线程的啊

  • #5 强击齐 1413524439968

    sd

  • #6 R1000 1413549562177

    你妈gwt事java编js,现在又搞go,真是闲的

  • #7 李杰雄 1413768609099

    貌似好厉害的样子

微信扫码 立即评论