Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

在windjs的基础上封装像golang一样的并行编程接口(内有代码) api like golang (code attach) #78

Open
bronze1man opened this issue Mar 4, 2013 · 1 comment

Comments

@bronze1man
Copy link

想法

模仿golang的接口,可以把windjs的接口做的更加抽象,和正交...
既然windjs可以把异步转为同步,golang也有办法把同步转为异步,异步转成同步.
为什么不尝试提供golang的并行编程接口呢?

实现

golang 有2个接口和并行编程有关:
1.创建goroute(线程) 如: go func(ch chan<- bool) { for { sleep(10); ch <- true; }} (c)
这个windjs本身已经提供.简单封装就可以了.
2.channel数据类型 如: go func(ch chan<- bool) { for { sleep(10); ch <- true; }} (c)
先用异步回调接口实现channel对象,后用windjs的接口把异步转为同步.实现了同步接口下的channel对象.

可以改进的地方

1.创建goroute的方法可以省掉.start()
2.没有实现带buffer的channel...
3.函数嵌套问题(不明白函数调用规则...召唤文档)


<script src='wind-all-0.7.3.js'></script>
<script>
var a=2;
//new thread 建立新线程
function go(cb){
    return eval(Wind.compile('async',cb));
}
//channel exchange data 使用channel发送数据,或者同步两个线程的执行
//异步channel对象
function channel(){
    return {
        'read_cb':[],
        'write_cb':[],
        'data':[],
        'read':function(cb){
            this.read_cb.push(cb);
            if (this.write_cb.length>0){
                this.do();
            }
        },
        'write':function(data,cb){
            this.data.push(data);
            this.write_cb.push(cb);
            if (this.read_cb.length>0){
                this.do();
            }
        },
        'do':function(){
            var read_cb = this.read_cb.pop();
            var write_cb = this.write_cb.pop();
            var data = this.data.pop();
            read_cb(data);
            write_cb();
        }
    };
}
var c1=new channel();
//测试异步channel对象
function test1(){
    c1.read(function(data){console.log(data);});
    c1.read(function(data){console.log(data);});
    c1.read(function(data){console.log(data);});
    c1.write('data_on_channel',function(){console.log('write finish1')});
    c1.write('data_on_channel',function(){console.log('write finish2')});
    c1.write('data_on_channel',function(){console.log('write finish3')});
    c1.read(function(data){console.log(data);});
    c1.write('data_on_channel',function(){console.log('write finish4')});
}
//同步channel对象
function channelAsync(){
    var origin = new channel();
    origin.read = Wind.Async.Binding.fromCallback(origin.read);
    origin.write = Wind.Async.Binding.fromCallback(origin.write);
    return origin;
}


//使用样例1
function test2(){
    var c2=new channelAsync();
    var reader = go(function(c){
        $await(Wind.Async.sleep(1000));
        console.log('start read');
        recv_data = $await(c.read());
        console.log('end read recv:'+recv_data);
    })(c2).start();
    var writer = go(function(c){
        $await(Wind.Async.sleep(100));
        console.log('start write');
        $await(c.write('send_data'));
        console.log('end write');
    })(c2).start();

}


//使用样例2
function test3(){
    var c=new channelAsync();
    for (i=0;i<10;i++){
        go(function(c,i){
            $await(Wind.Async.sleep(Math.random()*1000 ));
            $await(c.write('1'));
            console.log('read finish'+i);
        })(c,i).start();
    }
    go(function(c){
    for (i=0;i<10;i++){
        $await(c.read());
    }
    })(c).start();
}

setTimeout(test1,1000);
setTimeout(test2,2000);
setTimeout(test3,4000);
</script>
@bronze1man
Copy link
Author

然后我想试试复杂一点的情况,但是不知道如何用windjs完成它....到底哪些地方需要用$await呢?
golang代码如下...

package main
import "fmt"
import "time"
//同步转换为异步
func setTimeout(cb func(),timeout int){
    go func(){
        time.Sleep( time.Duration(int64(timeout)*1e9));
        cb();
    }()
}
//异步转换为同步
func sleep(timeout int){
    c:=make(chan int);
    go func(){
        setTimeout(func(){
            c<-1
        },timeout)
    }()
    <-c
}
func main(){
    setTimeout(func(){
        fmt.Println("after time out");
    },1);
    fmt.Println("before sleep");
    sleep(2);
    fmt.Println("after sleep");
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant