Асинхронный интерфейс ввода / вывода deno

#javascript #asynchronous #command-line-interface #chat #deno

#javascript #асинхронный #интерфейс командной строки #Чат #deno

Вопрос:

Я создаю программу чата в deno cli. Я уже написал функцию, которая получает новые сообщения и выводит их на экран каждые 1 секунду. При этом он также асинхронно прослушивает ввод cli (используя стандартные строки чтения deno), поэтому, когда пользователь нажимает enter, его сообщение отправляется. Однако, если вы пишете сообщение, и обновление происходит до того, как вы нажмете enter, новые сообщения будут записаны прямо рядом с тем, что вы писали, и вам нужно ввести его снова.

тест терминала

Как вы можете видеть, я печатал ерунду ( fdghsjkasjdhfv ), но Алиса hello снова сказала, что функция обновления запустилась и написала новое сообщение сразу после того, что я печатал.

Вопрос в том, есть ли способ сохранить введенный материал, очистить его и распечатать обратно, как только функция обновления разместит новые сообщения?

Код, который я использую:

 import { readLines } from "https://deno.land/std/io/mod.ts";

async function read() {
    for await(const line of readLines(Deno.stdin)) {
        if (!settings.printing) return line;
    }
}

let settings = { exit: false, user: 'anon', lastID: 0, printing: false };

async function main() {
    console.log('== DISCUSSION ==========================');
    printMessages();
    do {
        let line = await read();
        if (/^!s*(quit|exit)$/.test(line)) settings.exit = true;
        else sendMessage(line);
    } while (!exit);
}

await main();

function sendMessage(text) {
    postRequest('postMessage', {
        user: settings.user, data: text
    }).then(response => {
        if (response.status != 200) {
            console.log('[Connection Error!]');
            return;
        }
    });
}

function printMessages() {
    postRequest('getDiscussion', {
        id: settings.lastID // get the messages after the lastID received
    }).then(response => {
        if (response.status != 200) return;
        response.json().then(j => {
            if (j.length != 0) settings.lastID = j[j.length - 1].id;
            settings.printing = true;
            for (const m of j) {
                const time = new Date(m.time).toTimeString().slice(0, 5);
                console.log(
                    `[${time}][${m.user}]: `,
                    m.data
                );
            }
            settings.printing = false;
            if (!settings.exit) setTimeout(printMessages, 1000);
        });
    });
}


function postRequest(api, data) {
    let form = new FormData();
    for (const property in data) {
        form.append(property, data[property]);
    }
    return fetch(`https://example.com/api/${api}.php`, {
        method: "POST",
        body: form
    });
}

 

Комментарии:

1. почему вы не используете сокеты для чата в реальном времени?

2. Я просто не могу… Я ограничен API-интерфейсами php, mysql и js

3. это очень плохая практика, которую вы используете! в php есть поддержка сокетов. попробуйте.

4. да, я знаю, но в задании сказано использовать эти технологии. однако основной проблемой является асинхронный ввод / вывод….