Node.js и проблема node-gtk при выполнении асинхронного c кода из другого файла - PullRequest
5 голосов
/ 02 апреля 2020

У меня очень специфическая c проблема, я не уверен, может быть, это какая-то сборка мусора или другая проблема с node.js процессом, которая завершается sh во время работы приложения.

Так У меня есть реализация Scheme, написанная на JavaScript, и я пытаюсь запустить код Scheme, который является node-gtk basi c примером приложения с меткой. Проблема в том, что ярлык не вставлен в окно. У меня разбитое окно с фоном из-под экрана, которые остаются при перемещении окна.

enter image description here

У меня есть node.js исполняемый файл, который имеет этот shebang:

 #!/usr/bin/env node

, и мой код схемы - 1-1 demo от node-gtk , но в Scheme, который имеет это как shebang:

#!/home/kuba/projects/jcubic/lips/bin/lips.js

временный локальный экземпляр, потому что я работаю над следующей версией. Он также работает с:

#!/usr/bin/env lips

Вот часть кода моего REPL и выполнения файлов:

if (options._.length === 1) {
    fs.readFile(options._[0], function(err, data) {
        var e = env.inherit('name');
        if (err) {
            console.error(err);
        } else {
            boostrap(e).then(function() {
                return run(data.toString().replace(/^#!.*\n/, ''), e);
            });
            console.log('HELLO');
        }
    });
} else if (options.h) {
    var name = process.argv[1];
    console.log(format('%s\nusage:\n%s [-h]|[-c <code>]|<filename>\n\n\t-h this help message\n\t-c execute' +
                       ' code\n\nif called without arguments it will run REPL and if called with one argument' +
                       '\nit will treat it as filename and execute it.', intro, name));
} else {
    if (process.stdin.isTTY) {
        console.log(banner);
    }
    var prompt = 'lips> ';
    var continuePrompt = '... ';
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
        prompt: prompt,
        terminal: !!process.stdin.isTTY
    });
    if (process.stdin.isTTY) {
        rl.prompt();
    }
    var code = '';
    var multiline = false;
    var resolve;
    var e = env.inherit('name', {
        stdin: InputPort(function() {
            return new Promise(function(resolve) {
                rl.question('', resolve);
            });
        }),
        stdout: OutputPort(function(x) {
            //rl.write(this.get('repr')(x));
            console.log(this.get('repr')(x));
        })
    });
    boostrap(e).then(function() {
        rl.on('line', function(line) {
            code += line + '\n';
            if (balanced_parenthesis(code)) {
                rl.pause();
                run(code, e).then(function(result) {
                    if (process.stdin.isTTY) {
                        print(result);
                        if (multiline) {
                            rl.setPrompt(prompt);
                        }
                        rl.prompt();
                    }
                    rl.resume();
                }).catch(function() {
                    if (process.stdin.isTTY) {
                        if (multiline) {
                            rl.setPrompt(prompt);
                        }
                        rl.prompt();
                    }
                });
                code = '';
            } else {
                multiline = true;
                var i = indent(code, 2, prompt.length - continuePrompt.length);
                rl.setPrompt(continuePrompt);
                rl.prompt();
                rl.write(new Array(i + 1).join(' '));
            }
        });
    });
}

Если я выполняю первый оператор if, приложение node-gtk не работает как на проверенном экране, но если я запускаю как REPL с readline и копирую, вставляю тот же код, он работает. То же самое, если я запустил это:

../lips/bin/lips.js < ./run.scm

, но получил дополнительный «...» из многострочного регистра. Как правильно выполнить этот скрипт схемы?

Я также создал проблему в репозитории node-gtk https://github.com/romgrk/node-gtk/issues/170

Я также пытался используйте обещания:

// this is the object that hold references
// while the scheme code is running
let e = env.inherit('name'); 
fs.promises.readFile(options._[0]).then(function(data) {
    return boostrap(e).then(function() {
        return run(data.toString().replace(/^#!.*\n/, ''), e);
    });
}).catch(err => {
    console.error(err);
});

, но проблема остается.

bootstrap Функция просто загружает внешние файлы и запускает только оценку кода, поскольку строки, созданные в коде схемы, сохраняются в среде. (это простой объект в e.env).

Если я добавлю этот код:

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

до того, как мой код заработает, это будет своего рода хак. Почему это работает и есть ли лучший способ? Я хотел бы понять, почему это происходит и как это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...