go2js icon indicating copy to clipboard operation
go2js copied to clipboard

Channels and gorountines in js

Open vladimir-vg opened this issue 13 years ago • 1 comments

I also thought about go to js translator, pretty awesome idea.

What about this kind of channels/gorountines implementation:

var Go = (function () {
  var result = {package: {}};

    /* chan */

    var chan = function () {
        this.getCallbackStack = [];
        this.putCallbackStack = [];
    };

    chan.prototype.put = function (value, callback) {
        if (this.getCallbackStack.length == 0) {
            this.putCallbackStack.push({value: value, callback: callback});
        } else {
            var getCallback = this.getCallbackStack.pop().callback;
            if (getCallback) {
                getCallback(value);
            }
            if (callback) {
                callback();
            }
        }
    };

    chan.prototype.get = function (callback) {
        if (this.putCallbackStack.length == 0) {
            this.getCallbackStack.push({callback: callback});
        } else {
            var elt = this.putCallbackStack.pop();
            var putCallback = elt.callback, value = elt.value;
            if (callback) {
                callback(value);
            }
            if (putCallback) {
                putCallback();
            }
        }
    };

    result.chan = chan;

    /* goroutine */

    result.go = function (callback, arguments) {
        arguments = arguments || [];
        setTimeout(function () {
            callback.apply(null, arguments);
        }, 0);
    };

    result.println = function (value) {
        console.log(value);
    };

    return result;
})();

Go.package["time"] = {

    Second: 1000,

    Sleep: function (duration, callback) {
        setTimeout(callback, duration)
    }
};

And example of use:

// package main
//
// import "time"
//
// func main() {
//   ch := make(chan bool)
//  go func() {
//      println("Locked")
//      <-ch
//      println("Unlocked")
//      ch <- true
//  }()
//  time.Sleep(time.Second*2)
//  ch <- true
//  <- ch
// }

(function () {
    var time = Go.package["time"];
    var ch = new Go.chan();
    Go.go(function () {
        Go.println("Locked");
        ch.get(function (value) {
            Go.println("Unlocked");
            ch.put(true);
        });
    });
    time.Sleep(time.Second*2, function () {
        ch.put(true, function () {
            ch.get();
        });
    });
})();

This in this code channels have capacity equal to 1, but can be easily tuned to support buffered channels.

vladimir-vg avatar Jan 06 '13 09:01 vladimir-vg

It's awesome if it can be simulated.

Since the implementation of the JS library is done in Go (https://github.com/kless/go2js/blob/master/jslib/lib.go) I'll try do it on it, with your help and knowledge about callbacks in JS, to try that it can be done a line-to-line translataion.

tredoe avatar Jan 06 '13 13:01 tredoe