我正在使用GJS和GNOME平台在JavaScript中编写一个简单的桌面应用程序:GTK +,GLib,Gio,GObject。下面的代码说明了我面临的情况,并且更容易被复制,因为它不需要访问应用程序使用的文件。简而言之,我希望在完成一系列异步任务(加载一系列文件的内容)之后运行指定的代码行。我怎么能在GJS中做到这一点,最好是使用Gio或JavaScript本身的东西?
public void setCustomer(Customer customer) {...}
PS:在提供的代码中,在完成所有异步任务之前运行指定的代码行并不会阻止应用程序正常运行。但是,我想在应用程序启动时只对列表进行一次排序,而不是每次读取文件时对列表进行排序。而且,当然,知道如何做到这一点在另一种情况下也会有所帮助。
答案 0 :(得分:1)
如果我理解你要做的事情,你需要Promise.all()
之类的东西。不幸的是,GJS没有承诺库(还有。)
我建议在你的枚举儿童回调中做这样的事情(我编辑了一些与我试图说明的内容无关的部分):
_enumerateChildrenAsyncCallback: function(dir, result) {
let fileEnumerator = dir.enumerate_children_finish(result);
let displayName, file, fileInfo, fileType, iter;
let pendingOperations = new Set();
while ((fileInfo = fileEnumerator.next_file(null))) {
file = dir.get_child(fileInfo.get_name());
fileType = file.query_file_type(Gio.FileQueryInfoFlags.NONE, null);
if (fileType != Gio.FileType.REGULAR) continue;
pendingOperations.add(file);
file.load_contents_async(null, (file, result) => {
let [success, contents, etag] = file.load_contents_finish(result);
pendingOperations.delete(file);
if (pendingOperations.size === 0)
this.model.set_sort_column_id(0, Gtk.SortType.ASCENDING);
});
}
},
乍一看,这似乎在pendingOperations
清除其第一个元素和添加第二个元素之间存在竞争条件,但load_contents_async
回调不会开始被调用,直到主循环的下一次迭代,所以你应该在那里安全。