Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
GopherJS的goroutine中的死锁_Go_Deadlock_Gopherjs - Fatal编程技术网

GopherJS的goroutine中的死锁

GopherJS的goroutine中的死锁,go,deadlock,gopherjs,Go,Deadlock,Gopherjs,为什么在下面的代码中会出现死锁?我正试着把一些东西从goroutine带回外面 package main import ( "fmt" "syscall/js" "time" ) func test(this js.Value, i []js.Value) interface{} { done := make(chan string, 1) go func() { doRequest := func(this js.Value, i

为什么在下面的代码中会出现死锁?我正试着把一些东西从goroutine带回外面

package main

import (
    "fmt"
    "syscall/js"
    "time"
)

func test(this js.Value, i []js.Value) interface{} {
    done := make(chan string, 1)

    go func() {
        doRequest := func(this js.Value, i []js.Value) interface{} {
            time.Sleep(time.Second)

            return 0
        }

        js.Global().Set("doRequest", js.FuncOf(doRequest))
        args := []js.Value{js.ValueOf("url")}
        var x js.Value
        doRequest(x, args)
        done <- "true"
    }()

    aa := <-done
    fmt.Println(aa)

    return 0
}

func main() {
    c := make(chan bool)
    js.Global().Set("test", js.FuncOf(test))
    <-c
}
func main(){
c:=制造(陈布尔)
js.Global().Set(“test”,js.FuncOf(test))

与错误消息中所说的差不多。所有goroutine都处于休眠状态。
main
不启动任何内容,只执行一个通道接收,因此它被阻止,并且没有其他goroutine正在运行,因此
main
不可能再次唤醒,因此运行时陷入恐慌

如果我没记错的话,与常规围棋不同,GopherJS不会在
main
退出时关闭所有东西并退出(部分原因是:这到底意味着什么?与围棋程序最接近的模拟是关闭网页!这有点糟糕。所以GopherJS不会这样做。)所以严格地说,在GopherJS中,保持
main
活动的操作是不必要的

这就是说,如果你在最后说(例如)
time.Sleep(time.Hour)
,那么当所有的goroutine仍然处于睡眠状态时(严格地说),
main
最终会被唤醒,运行时知道这一点,所以在这种情况下它不会惊慌失措

对于实际的
test
函数,一旦您尝试了它,就会得到一条相关的错误消息:
Uncaught error:runtime error:cannot block in JavaScript callback,通过在goroutine
中包装代码来修复
test
对通道执行阻塞调用,而GopherJS不允许在直接从JavaScript调用的函数中执行该操作,所以它很恐慌。(当我在中运行它时,我还得到了
未捕获的TypeError:r不是一个函数,但这只是早期错误的后果。)

我认为您要做的是等待
doRequest
完成,打印值并返回,但这不起作用。为此,您需要使用本机Javascript承诺或其他异步机制。

谢谢,这完全是有意义的。我正在尝试使用I.e
js.Global().Get(“console”).Call将值写入console(“log”,value.String())
它可以工作。但是当我尝试将值发送到chrome扩展时,不知何故我无法使用
js.Global().Get(“chrome”).Get(“runtime”).Call(“sendMessage”,“extension\u id”,“message::”+value.String())接收消息
但是,我想这是一个不同的问题。我会接受这个答案。@iesiyok获取
控制台的一个更简单的方法。log
就是
println
-这被认为是非阻塞的,所以它工作正常。尝试向分机发送消息将是一个阻塞调用(我假设),所以,是的,你必须尝试其他方法。我最终用
js.Global().Set(“anObject”,obj)
定义了一个对象,并在go部分调用
js.Global().Get(“window”).Call(“assignedObjectCallback”)后在后台脚本中使用“anObject”
分配对象后。它现在工作正常,我假设这不是阻塞,但我不确定。
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
.....
func main() {
    c := make(chan bool)
    js.Global().Set("test", js.FuncOf(test))
    <-c
}