Memblokir readline, membuka blokir perilaku
Bayangkan Anda memiliki tiga pertanyaan yang harus dijawab dari konsol, karena Anda sekarang tahu kode ini tidak akan berjalan karena modul standar readline memiliki perilaku 'tidak terblokir' yang mengatakan setiap rl.pertanyaan adalah utas independen sehingga kode ini tidak akan berjalan.
'use strict';
var questionaire=[['First Question: ',''],['Second Question: ',''],['Third Question: ','']];
function askaquestion(question) {
const readline = require('readline');
const rl = readline.createInterface(
{input: process.stdin, output:process.stdout}
);
rl.question(question[0], function(answer) {
console.log(answer);
question[1] = answer;
rl.close();
});
};
var i=0;
for (i=0; i < questionaire.length; i++) {
askaquestion(questionaire[i]);
}
console.log('Results:',questionaire );
Menjalankan output:
node test.js
Third Question: Results: [ [ 'First Question: ', '' ],
[ 'Second Question: ', '' ],
[ 'Third Question: ', '' ] ] <--- the last question remain unoverwritten and then the final line of the program is shown as the threads were running waiting for answers (see below)
aaa <--- I responded with a single 'a' that was sweeped by 3 running threads
a <--- Response of one thread
a <--- Response of another thread
a <--- Response of another thread (there is no order on threads exit)
Solusi yang diusulkan menggunakan emitor peristiwa untuk memberi sinyal akhir dari unblocking thread, dan termasuk loop logika dan akhir program ke dalam fungsi pendengarnya.
'use strict';
var questionaire=[['First Question: ',''],['Second Question: ',''],['Third Question: ','']];
// Introduce EventEmitter object
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {};
const myEmitter = new MyEmitter();
myEmitter.on('continue', () => {
console.log('continue...');
i++; if (i< questionaire.length) askaquestion(questionaire[i],myEmitter); // add here relevant loop logic
else console.log('end of loop!\nResults:',questionaire );
});
//
function askaquestion(p_question,p_my_Emitter) { // add a parameter to include my_Emitter
const readline = require('readline');
const rl = readline.createInterface(
{input: process.stdin, output:process.stdout}
);
rl.question(p_question[0], function(answer) {
console.log(answer);
p_question[1] = answer;
rl.close();
myEmitter.emit('continue'); // Emit 'continue' event after the question was responded (detect end of unblocking thread)
});
};
/*var i=0;
for (i=0; i < questionaire.length; i++) {
askaquestion(questionaire[i],myEmitter);
}*/
var i=0;
askaquestion(questionaire[0],myEmitter); // entry point to the blocking loop
// console.log('Results:',questionaire ) <- moved to the truly end of the program
Menjalankan output:
node test2.js
First Question: 1
1
continue...
Second Question: 2
2
continue...
Third Question: 3
3
continue...
done!
Results: [ [ 'First Question: ', '1' ],
[ 'Second Question: ', '2' ],
[ 'Third Question: ', '3' ] ]
rl
maksud Anda readline ?