GopherJS的goroutine中的死锁
为什么在下面的代码中会出现死锁?我正试着把一些东西从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
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.ejs.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
}