首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从gjs读取异步标准输出

从gjs读取异步标准输出
EN

Stack Overflow用户
提问于 2015-10-31 12:19:50
回答 1查看 990关注 0票数 2

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

这是我的同步代码

代码语言:javascript
复制
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);

这很好,但是如果我尝试异步地做它,它就不能工作

代码语言:javascript
复制
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;
}

根本不调用回调。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-11-29 13:54:14

首先,谢谢您的提问,我也有同样的基本问题,也就是您的第一行“我试图从gjs运行一个命令并异步读取输出”,而您的问题包含了我找到解决方案所需的详细信息!

在您的示例代码中,主要的问题是以下几行:

代码语言:javascript
复制
while(true){
   i = 0;
}

在得到输出之前,您正确地试图阻止程序终止,但是这个解决方案不起作用。

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

你想要的是进入一个事件循环。如果您正在开发Gnome Shell扩展,您已经在其中运行了,但是如果您只是使用Gjs运行一个脚本,则需要显式地启动一个脚本。我将使用Clutter,但其他一些事件循环也会同样有效。以下代码段构成完整的工作解决方案。

首先,我们从导入所需的库开始:

代码语言:javascript
复制
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const Clutter = imports.gi.Clutter;

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

代码语言:javascript
复制
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的提升,可以在这里使用):

代码语言:javascript
复制
out_reader.read_upto_async("", 0, 0, null, _SocketRead, "");

并启动事件循环:

代码语言:javascript
复制
Clutter.init(null);
Clutter.main();

回调中有几个错误,因此这里有一个固定版本,一旦命令停止产生输出,事件循环也会终止:

代码语言:javascript
复制
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();
  } 
} 

为了进一步阅读,在https://gjs-docs.gnome.org/上有Gjs本机绑定文档。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33451496

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档