You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GNOME扩展中使用replace_contents_bytes_async写入文件报错求助

解决GNOME扩展中replace_contents_bytes_async写入文件的报错问题

问题根源在于Gio的replace_contents_bytes_async是回调式异步方法,无法直接用await调用——即使添加了回调函数,该方法也不会返回Promise,await无法处理它的返回值,因此报错。

以下是两种可行的修复方案:

方案1:用GLib.promisify转换为Promise

借助GLib工具将回调式方法转为Promise,适配await语法:

import { Extension } from 'resource:///org/gnome/shell/extensions/extension.js';
import GLib from 'gi://GLib';
import Gio from 'gi://Gio';

export default class ExampleExtension extends Extension {
    async enable() {      
        const file = Gio.File.new_for_path('/tmp/test-file.txt');
        const bytes = new GLib.Bytes('some file contents');
        
        // 将回调式异步方法转为Promise
        const replaceContentsBytes = GLib.promisify(file.replace_contents_bytes_async, file);
        const [etag] = await replaceContentsBytes(
            bytes, 
            null, 
            false, 
            Gio.FileCreateFlags.REPLACE_DESTINATION, 
            null
        );
        console.log('文件写入完成,ETag:', etag);
    }

    disable() {
    }
}

方案2:手动用Promise包装回调

手动封装Promise,在回调中调用finish方法获取结果:

import { Extension } from 'resource:///org/gnome/shell/extensions/extension.js';
import GLib from 'gi://GLib';
import Gio from 'gi://Gio';

export default class ExampleExtension extends Extension {
    async enable() {      
        const file = Gio.File.new_for_path('/tmp/test-file.txt');
        const bytes = new GLib.Bytes('some file contents');
        
        const [etag] = await new Promise((resolve, reject) => {
            file.replace_contents_bytes_async(
                bytes, 
                null, 
                false, 
                Gio.FileCreateFlags.REPLACE_DESTINATION, 
                null, 
                (source, res) => {
                    try {
                        // 调用finish方法获取最终结果
                        const result = source.replace_contents_bytes_finish(res);
                        resolve(result);
                    } catch (e) {
                        reject(e);
                    }
                }
            );
        });
        console.log('文件写入完成,ETag:', etag);
    }

    disable() {
    }
}

关键说明

Gio异步方法遵循固定流程:调用*_async方法发起请求,必须在回调中调用对应的*_finish方法来获取结果或捕获错误,这是解决问题的核心。

内容的提问来源于stack exchange,提问作者ibse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 19:55:59