2015-10-31 123 views
1

我试图从gjs运行一个命令并异步读取输出。从gjs读取异步标准输出

这里是我的代码同步

let [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null, 
                ['/bin/ls'], null, 0, null); 
let out_reader = new Gio.DataInputStream({ 
    base_stream: new Gio.UnixInputStream({fd: out_fd}) 
}); 
var out = out_reader.read_until("", null); 
print(out); 

这个工作正常,但如果我尝试以异步方式去做它不工作

let [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null, 
                ['/bin/ls'], null, 0, null); 
let out_reader = new Gio.DataInputStream({ 
    base_stream: new Gio.UnixInputStream({fd: out_fd}) 
}); 
function _SocketRead(source_object, res, user_data){ 
    print("hi"); 
    let length; 
    let out = out_reader.read_upto_finish(asyncResult, length); 
    print("out" + out); 
    print("length" + length); 
} 
var out = out_reader.read_upto_async("",0, 0, null, _SocketRead, ""); 
while(true){ 
    i = 0; 
} 

回调根本没有被

回答

2

称为首先感谢你的问题,我也有同样的基础问题,也就是你的初始行“我试图从gjs运行一个命令并异步读取输出”以及你的任务离子有我需要找到解决方案的细节!

在你的示例代码,主要的问题是,这些行:

while(true){ 
    i = 0; 
} 

您正确试图从你得到的输出之前终止保持程序,但这种方法是行不通的。

Javascript是单线程的,这意味着虽然计算可以以串行交错方式同时运行,但不能同时运行两个Javascript计算。没有办法明确地产生线程,问题中的忙碌循环只是继续旋转,回调永远不会获得CPU时间。

你想要的是进入事件循环。如果您正在开发Gnome Shell扩展,那么您已经在运行一个,但如果您只是使用Gjs运行脚本,则需要明确启动一个。我将使用Clutter,但其他一些事件循环也可以做到。以下代码段构成完整的工作解决方案。

首先,让我们通过导入所需的库开始:

const GLib = imports.gi.GLib; 
const Gio = imports.gi.Gio; 
const Clutter = imports.gi.Clutter; 

然后从添加问题产卵和文件描述符:

const [res, pid, in_fd, out_fd, err_fd] = GLib.spawn_async_with_pipes(null, ['/bin/ls'], null, 0, null); 
const out_reader = new Gio.DataInputStream({ 
    base_stream: new Gio.UnixInputStream({fd: out_fd}) 
}); 

调用异步读取功能,并给它一个回调(定义如下,这里可以在Javascript中使用):

out_reader.read_upto_async("", 0, 0, null, _SocketRead, ""); 

和启动事件循环:

​​

有在回调一对夫妇的错误,所以在这里固定的版本,也终止事件循环一旦命令停止产生输出:

function _SocketRead(source_object, res){ 
    const [out, length] = out_reader.read_upto_finish(res); 
    if (length > 0) { 
    print("out: " + out); 
    print("length: " + length); 
    out_reader.read_upto_async("", 0, 0, null, _SocketRead, ""); 
    } else { 
    Clutter.main_quit(); 
    } 
} 

对于进一步阅读有Gjs本地绑定文档在https://people.gnome.org/~gcampagna/docs