节点读取线输入重叠

时间:2018-04-27 20:25:32

标签: javascript node.js readline

当我有多个readline对象时,即使它们在同一个闭包中被打开和关闭,我最终也会看到奇怪的行为。

在我练习制作的tick tac toe游戏中,我遇到readline.interface.question终止而没有接收输入而没有输入回调的问题。

在下面的案例中,我试图隔离问题,提示偶尔复制我的输入(例如输入" 1"结果" 11")

如何同步使用readline.interface.question

const EventEmitter = require('events');
const readline = require('readline');



function Emitter() {
    EventEmitter.call(this);
    this.val = 1;
    this.ping = () => {
        console.log(this.val);
        readAndPrint(() => {
            this.emit('emit');
        });
    }

    this.setEmitter = (emitter) => {
        emitter.on('emit', this.ping);
    }

    const readAndPrint = (callback) => {
        const reader = readline.createInterface({
            input: process.stdin,
            output: process.stdout,
        });

        reader.question('Enter a string: ', (answer) => {
            reader.close();
            console.log(answer);
            callback();
        })
    }
}
Emitter.prototype.__proto__ = EventEmitter.prototype;




let one = new Emitter();
let two = new Emitter();
let three = new Emitter();
one.setEmitter(three);
two.setEmitter(one);
three.setEmitter(one);

one.ping();

1 个答案:

答案 0 :(得分:1)

我的猜测是因为你setEmitter时所有的this.pings都是由相同的“emit”触发的。因此,在你的one.ping()之后,回调触发一个“发出”并且这个为两个,三个在一个关闭后关闭。

你可以尝试给每个发射器一个id,这样它们就不会触发每个发射器的this.ping

const EventEmitter = require("events");
const readline = require("readline");

function Emitter(id) {
    EventEmitter.call(this);
    this.val = 1;
    this.id = id;
    this.ping = () => {
        console.log(this.val);
        readAndPrint(() => {
            this.emit("emit" + this.id);
        });
    };

    this.setEmitter = emitter => {
        emitter.on("emit" + this.id, this.ping);
    };

    const readAndPrint = function(callback) {
        const reader = readline.createInterface({
            input: process.stdin,
            output: process.stdout
        });

        reader.question("Enter a string: ", answer => {
            reader.close();
            console.log(answer);
            callback();
        });
    };
}
Emitter.prototype.__proto__ = EventEmitter.prototype;

let one = new Emitter(1);
let two = new Emitter(2);
let three = new Emitter(3);
one.setEmitter(three);
two.setEmitter(one);
three.setEmitter(one);

one.ping();

这是一个片段,可以让您更好地了解正在发生的事情。 基本上你的代码调用one.ping(),它关闭然后是两个.ping和three.ping从你的回调“emit”开始

const EventEmitter = require("events");
const readline = require("readline");

function Emitter(id) {
    EventEmitter.call(this);
    this.val = 1;
    this.id = id;
    this.ping = () => {
        readAndPrint(() => {
            this.emit("emit");
        });
    };

    this.setEmitter = emitter => {
        emitter.on("emit", this.ping);
    };

    const readAndPrint = callback => {
        console.log("my id is:", this.id);
        const reader = readline.createInterface({
            input: process.stdin,
            output: process.stdout
        });

        reader.question("Enter a string: ", answer => {
            reader.close();
            console.log(answer);
            callback();
        });
    };
}
Emitter.prototype.__proto__ = EventEmitter.prototype;

let one = new Emitter(1);
let two = new Emitter(2);
let three = new Emitter(3);
one.setEmitter(three);
two.setEmitter(one);
three.setEmitter(one);

one.ping();

要同步执行,您可以使用如下回调:

const EventEmitter = require("events");
const readline = require("readline");

function Emitter(id) {
    EventEmitter.call(this);
    this.val = 1;
    this.id = id;
    this.ping = cb => {
        readAndPrint(() => {
            this.emit("emit" + this.id);
            if (cb) {
                cb();
            }
        });
    };

    this.setEmitter = emitter => {
        emitter.on("emit" + this.id, this.ping);
    };
    this.removeListener = emitter => {
        emitter.removeListener();
    };

    const readAndPrint = callback => {
        const reader = readline.createInterface({
            input: process.stdin,
            output: process.stdout
        });

        reader.question("Enter a string: ", answer => {
            console.log("my id is: ", this.id);
            reader.close();
            console.log(answer);
            callback();
        });
    };
}
Emitter.prototype.__proto__ = EventEmitter.prototype;

let one = new Emitter(1);
let two = new Emitter(2);
let three = new Emitter(3);
one.setEmitter(three);
two.setEmitter(one);
three.setEmitter(one);

one.ping(() => two.ping());