ইন্টারেক্টিভভাবে কনসোল থেকে মান পড়া


155

আমি ভেবেছিলাম কিছু কনসোল এক্সটেনশন দিয়ে একটি সাধারণ সার্ভার HTTP সার্ভার তৈরি করব। কমান্ড লাইন ডেটা থেকে পড়ার জন্য আমি স্নিপেটটি পেয়েছি।

  var i = rl.createInterface(process.stdin, process.stdout, null);
  i.question('Write your name: ', function(answer) {
    console.log('Nice to meet you> ' + answer);
    i.close();
    process.stdin.destroy();

  });

বার বার প্রশ্ন জিজ্ঞাসা করা ভাল, আমি while(done) { }লুপ ব্যবহার করতে পারবেন না ? এছাড়াও সার্ভার যদি প্রশ্ন সময়ে আউটপুট গ্রহণ করে তবে এটি লাইনটি নষ্ট করে দেয়।


5
আমি rlআপনার দ্বারা পাঠ্যরেখা বোঝাচ্ছি ?
jpaugh

আপনি এই উত্তরের মতো নন-ব্লকিং ইন্টারফেস ব্যবহার করতে পারেন, তারপরে আপনি একটি while(done)লুপ করতে পারেন ।
কিভান

উত্তর:


182

আপনি একটি "যখন (সম্পন্ন)" লুপটি করতে পারবেন না কারণ এর জন্য ইনপুটটিতে ব্লক করা দরকার, নোড.জেএস কিছু করতে পছন্দ করে না।

পরিবর্তে প্রতিবার কিছু প্রবেশ করার সময় কল করার জন্য একটি কলব্যাক সেট আপ করুন:

var stdin = process.openStdin();

stdin.addListener("data", function(d) {
    // note:  d is an object, and when converted to a string it will
    // end with a linefeed.  so we (rather crudely) account for that  
    // with toString() and then trim() 
    console.log("you entered: [" + 
        d.toString().trim() + "]");
  });

2
আপনাকে ধন্যবাদ এই কাজ করে, "শেষ" শ্রোতা কিছু সমাপ্তির ক্রিয়াকলাপ কল করতে এবং 'বিদায়' বলতে অনুমতি দেয়?
রিস্তো নভিক

আমি উদাহরণটি থেকে "শেষ" শ্রোতাদের সরিয়ে দিয়েছি, সত্যই সত্যবাদী হওয়ার পক্ষে এটি কোথায় কার্যকর হবে তা আমি জানি না।
ছিনতাই করুন

2
আপনি স্ট্রিং আউটপুট d.toString ()। ট্রিম () এ সহজ করতে পারেন
এমকেএন ওয়েব সলিউশন

6
এই উত্তরটির তারিখ ২০১১ এবং এর পরে অনেক কিছু পরিবর্তন হয়েছে। বিশেষত, উত্তরের প্রথম অংশটি, আপনি কিছুক্ষণ লুপ করতে পারবেন না ... আর ধরে রাখবেন না। হ্যাঁ, আপনি কিছুক্ষণ লুপ রাখতে পারেন এবং এখনও অবরুদ্ধ করতে পারবেন না, অ্যাসিঙ্ক-প্রতীক্ষিত প্যাটার্নের জন্য ধন্যবাদ। অন্যান্য উত্তর যে প্রতিফলিত। আজকাল যে কারও কাছে এটি পড়ছে - দয়া করে অন্যান্য উত্তরগুলির সাথেও পরামর্শ করুন।
উইক্টর জাচলা

1
@ উইক্টরজাইচলায় অনুসরণ করতে, 2011.-এর প্রায়শই কাজ করার সময় ফাংশন প্রক্রিয়া.অপেনস্ট্যান্ডিনকে অবহেলা করা হয়েছিল এবং আপনি এ সংক্রান্ত কোনও দলিল পাবেন না।
calder.ty

111

আমি এই উদ্দেশ্যে অন্য একটি API ব্যবহার করেছি ..

var readline = require('readline');
var rl = readline.createInterface(process.stdin, process.stdout);
rl.setPrompt('guess> ');
rl.prompt();
rl.on('line', function(line) {
    if (line === "right") rl.close();
    rl.prompt();
}).on('close',function(){
    process.exit(0);
});

উত্তরটি না পাওয়া পর্যন্ত এটি লুপটিতে প্রম্পট করতে দেয় right। এছাড়াও এটি দুর্দান্ত সামান্য কনসোল দেয় You আপনি বিশদটি জানতে পারেন @ http://nodejs.org/api/readline.html#readline_example_tiny_cli


11
এটি একটি দুর্দান্ত উত্তর। যা সুস্পষ্ট নাও হতে পারে (তবে এটি একটি বড় প্লাস) তা হ'ল পঠনরেখা বাহ্যিক নির্ভরতা নয়: এটি নোড.জেএস এর অংশ part
jlh

51

রিডলাইন এপিআই 12 থেকে বেশ কিছুটা পরিবর্তন হয়েছে has মানক স্ট্রিম থেকে ব্যবহারকারী ইনপুট ক্যাপচার করতে ডকটির একটি দরকারী উদাহরণ দেখানো হয়েছে:

const readline = require('readline');

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

rl.question('What do you think of Node.js? ', (answer) => {
  console.log('Thank you for your valuable feedback:', answer);
  rl.close();
});

আরও তথ্য এখানে।


5
এটি কেবল একটি প্রাথমিক উদাহরণ। আপনি কীভাবে ইন্টারঅ্যাক্ট করবেন? প্রশ্ন উত্তর? একাধিক পছন্দ এবং মত? কীভাবে আরএল একবার বন্ধ হয়ে যায়, কীভাবে কিছু যুক্তি সহ ব্যবহারকারীর সাথে আলাপ করতে ওপেন আরএল দিয়ে কাজ করতে না
পারলে

27

আমি বিশ্বাস করি এটি async-awaitনোড> = 7.x ব্যবহৃত হয়েছে ধরে ধরেই একটি আধুনিক উত্তর প্রাপ্য ।

উত্তরটি এখনও ব্যবহার করে ReadLine::questionতবে এটি আবৃত করে যাতে while (done) {}সম্ভব হয়, যা ওপি স্পষ্টতই জিজ্ঞাসা করে।

var cl = readln.createInterface( process.stdin, process.stdout );
var question = function(q) {
    return new Promise( (res, rej) => {
        cl.question( q, answer => {
            res(answer);
        })
    });
};

এবং তারপরে একটি উদাহরণ ব্যবহার

(async function main() {
    var answer;
    while ( answer != 'yes' ) {
        answer = await question('Are you sure? ');
    }
    console.log( 'finally you are sure!');
})();

নিম্নলিখিত কথোপকথন বাড়ে

Are you sure? no
Are you sure? no
Are you sure? yes
finally you are sure!

ঠিক এই উত্তরটি আমি খুঁজছিলাম। আমি মনে করি এটি শীর্ষস্থানীয় হওয়া উচিত।
উইলিয়াম চৌ চৌ

সুন্দর। বৃহত্তর স্ক্রিপ্টগুলির জন্য অ্যাসিঙ্ক প্রতীক্ষার প্রয়োজন। এটাই আমার দরকার ছিল।
অভয় শিরো

25

দয়া করে রিডলাইন-সিঙ্ক ব্যবহার করুন , এটি আপনাকে সিঙ্ক্রোনাস কনসোল আউটআউট কলব্যাকস হেলসের সাথে কাজ করতে দেয়। এমনকি পাসওয়ার্ড সহ কাজ করে:

var favFood = read.question('What is your favorite food? ', {
  hideEchoBack: true // The typed text on screen is hidden by `*` (default). 
});


5
এটির জন্য অতিরিক্ত নির্ভরতা প্রয়োজন তাই আমি অন্যান্য সমাধানগুলি পছন্দ করব।
রিস্তো নভিক

এসওতে চালিত হয় না "অব্যাহত রেফারেন্স এরর: পাঠ্য সংজ্ঞায়িত করা হয়নি"
অজম্ম

12

@ আরব উত্তর বেশিরভাগ সময় কাজ করবে, তবে দীর্ঘ ইনপুটগুলির সাথে প্রত্যাশা মতো এটি কাজ করতে পারে না।

পরিবর্তে আপনার এটি ব্যবহার করা উচিত:

const stdin = process.openStdin();
let content = '';

stdin.addListener('data', d => {
  content += d.toString();
});

stdin.addListener('end', () => {
  console.info(`Input: ${content}`);
});

কেন এই সমাধান কাজ করে সে সম্পর্কে ব্যাখ্যা:

addListener('data') বাফারের মতো কাজ করে, যখন পূর্ণ হয় বা / এবং এর ইনপুট শেষ হয় তখন কলব্যাক কল করা হবে।

দীর্ঘ ইনপুট সম্পর্কে কি? একটি একক 'data'কলব্যাক যথেষ্ট হবে না, সুতরাং এটি আপনার ইনপুট দুটি বা ততোধিক অংশে বিভক্ত করবে। এটি প্রায়শই সুবিধাজনক নয়।

addListener('end')স্ট্যান্ডিন পাঠক যখন আমাদের ইনপুটটি পড়া শেষ করেন তখন আমাদেরকে অবহিত করবে। যেহেতু আমরা পূর্ববর্তী ডেটা সংরক্ষণ করে চলেছি, আমরা এখন এটি সমস্ত এক সাথে পড়তে এবং প্রক্রিয়া করতে পারি।


3
যখন আমি উপরের কোডটি ব্যবহার করছি এবং কিছু ইনপুট sertোকাচ্ছি এবং তারপরে "প্রবেশ" কীটি আরও ইনপুট চেয়ে আমাকে জিজ্ঞাসা করুন। আমরা এটিকে কতক্ষণ শেষ করব?
মাতান টুবুল

5

আমি ইনকয়েরার ব্যবহার করার পরামর্শ দিচ্ছি , যেহেতু এটি সাধারণ ইন্টারেক্টিভ কমান্ড লাইন ব্যবহারকারী ইন্টারফেসের সংগ্রহ সরবরাহ করে।

const inquirer = require('inquirer');

const questions = [{
  type: 'input',
  name: 'name',
  message: "What's your name?",
}];

const answers = await inquirer.prompt(questions);
console.log(answers);

5

এখানে একটি উদাহরণ:

const stdin = process.openStdin()

process.stdout.write('Enter name: ')

stdin.addListener('data', text => {
  const name = text.toString().trim()
  console.log('Your name is: ' + name)

  stdin.pause() // stop reading
})

আউটপুট:

Enter name: bob
Your name is: bob

ভাল উত্তর ভাই !! শুধু সহজ এবং পরিষ্কার।
এমডি জুলহাস হোসেইন

3

এটি অত্যধিক জটিল। এর একটি সহজ সংস্করণ:

var rl = require('readline');
rl.createInterface... etc

ব্যবহার করা হবে

var rl = require('readline-sync');

তারপরে এটি অপেক্ষা করবে যখন আপনি ব্যবহার করবেন

rl.question('string');

তারপরে এটি পুনরাবৃত্তি করা সহজ। উদাহরণ স্বরূপ:

var rl = require('readline-sync');
for(let i=0;i<10;i++) {
    var ans = rl.question('What\'s your favourite food?');
    console.log('I like '+ans+' too!');
}

2

অ্যাপ্লিকেশনটির পক্ষে একটি জেনেরিক প্রম্পট প্রদর্শন করা এবং এটি একটি স্যুইচ বিবৃতিতে হ্যান্ডেল করা সম্ভবত একটি সাধারণ ব্যবহারের কেস।

কল্পব্যাকটিতে নিজেকে কল করে এমন কোনও সহায়ক ফাংশন ব্যবহার করে আপনি কিছুক্ষণের লুপের সমতুল্য আচরণ পেতে পারেন:

const readline = require('readline');
const rl = readline.createInterface(process.stdin, process.stdout);

function promptInput (prompt, handler)
{
    rl.question(prompt, input =>
    {
        if (handler(input) !== false)
        {
            promptInput(prompt, handler);
        }
        else
        {
            rl.close();
        }
    });
}

promptInput('app> ', input =>
{
    switch (input)
    {
        case 'my command':
            // handle this command
            break;
        case 'exit':
            console.log('Bye!');
            return false;
    }
});

'app> 'যদি আপনার অ্যাপ্লিকেশনটি ইতিমধ্যে এই লুপের বাইরের স্ক্রিনে কিছু প্রিন্ট করে তবে আপনি খালি স্ট্রিংটি পাস করতে পারেন।


2

এটিতে আমার দৃষ্টিভঙ্গি হবে অ্যাসিঙ্ক জেনারেটর ব্যবহার করা ।

ধরে নিচ্ছি আপনার কাছে প্রশ্নের একটি অ্যারে রয়েছে:

 const questions = [
        "How are you today ?",
        "What are you working on ?",
        "What do you think of async generators ?",
    ]

awaitকীওয়ার্ডটি ব্যবহার করার জন্য আপনাকে অবশ্যই আপনার প্রোগ্রামটি একটি অ্যাসিঙ্ক আইআইএফইতে আবৃত করতে হবে।

(async () => {

    questions[Symbol.asyncIterator] = async function * () {
        const stdin = process.openStdin()

        for (const q of this) {
            // The promise won't be solved until you type something
            const res = await new Promise((resolve, reject) => {
                console.log(q)

                stdin.addListener('data', data => {
                    resolve(data.toString())
                    reject('err')
                });
            })

            yield [q, res];
        }

    };

    for await (const res of questions) {
        console.log(res)
    }

    process.exit(0)
})();

প্রত্যাশিত ফলাফল:

How are you today ?
good
[ 'How are you today ?', 'good\n' ]
What are you working on ?
:)
[ 'What are you working on ?', ':)\n' ]
What do you think about async generators ?
awesome
[ 'What do you think about async generators ?', 'awesome\n' ]

আপনি যদি সামগ্রিকভাবে কোনও উত্তর পেতে চান তবে আপনি একটি সাধারণ পরিবর্তনের মাধ্যমে এটি অর্জন করতে পারেন:

const questionsAndAnswers = [];

    for await (const res of questions) {
        // console.log(res)
        questionsAndAnswers.push(res)
    }

    console.log(questionsAndAnswers)

   /*
     [ [ 'How are you today ?', 'good\n' ],
     [ 'What are you working on ?', ':)\n' ],
     [ 'What do you think about async generators ?', 'awesome\n' ] ]
   */

2

আমাকে নোডে একটি "টিকি-ট্যাক-টো" গেমটি লিখতে হয়েছিল যা কমান্ড লাইন থেকে ইনপুট নিয়েছিল এবং এই বেসিক অ্যাসিঙ্কটি / কোডটির অপেক্ষার ট্রিকটি লিখেছিল।

const readline = require('readline')

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

async function getAnswer (prompt) {
  const answer = await new Promise((resolve, reject) =>{
    rl.question(`${prompt}\n`, (answer) => {
      resolve(answer)
    });
  })
  return answer
}

let done = false
const playGame = async () => {
  let i = 1
  let prompt = `Question #${i}, enter "q" to quit`
  while (!done) {
    i += 1
    const answer = await getAnswer(prompt)
    console.log(`${answer}`)
    prompt = processAnswer(answer, i)
  }
  rl.close()
}

const processAnswer = (answer, i) => {
  // this will be set depending on the answer
  let prompt = `Question #${i}, enter "q" to quit`
  // if answer === 'q', then quit
  if (answer === 'q') {
    console.log('User entered q to quit')
    done = true
    return
  }
  // parse answer

  // if answer is invalid, return new prompt to reenter

  // if answer is valid, process next move

  // create next prompt
  return prompt
}

playGame()

1

রিডলাইন অবরোধযুক্ত আচরণ অবরুদ্ধ করা হচ্ছে

কনসোল থেকে আপনার কাছে তিনটি প্রশ্নের জবাব দেওয়ার কথা কল্পনা করুন, আপনি এখন জানেন যে এই কোডটি চলবে না কারণ পাঠ্যরেখার স্ট্যান্ডার্ড মডিউলটি 'আনব্লকড' আচরণ বলেছে যে প্রতিটি rl.question একটি স্বাধীন থ্রেড তাই এই কোডটি চলবে না।

'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 );

চলমান আউটপুট:

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)

প্রস্তাবিত সমাধানটি একটি আনব্লকিং থ্রেডের সমাপ্তির সংকেত দিতে ইভেন্ট ইমিটার ব্যবহার করে এবং এতে লুপ লজিক এবং প্রোগ্রামটির শেষ অংশটি তার শ্রোতার ফাংশনে অন্তর্ভুক্ত করে।

'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

চলমান আউটপুট:

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' ] ]

0

আমি পড়ার ডিরেক্টরিটির জন্য একটি ছোট স্ক্রিপ্ট তৈরি করেছি এবং একটি কনসোল নামের নতুন ফাইল (উদাহরণ: 'name.txt') এবং ফাইলে পাঠ্য লিখি।

const readline = require('readline');
const fs = require('fs');

const pathFile = fs.readdirSync('.');

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

file.question('Insert name of your file? ', (f) => {
  console.log('File is: ',f.toString().trim());
  try{
    file.question('Insert text of your file? ', (d) => {
      console.log('Text is: ',d.toString().trim());
      try {
        if(f != ''){
          if (fs.existsSync(f)) {
            //file exists
            console.log('file exist');
            return file.close();
          }else{
            //save file
            fs.writeFile(f, d, (err) => {
                if (err) throw err;
                console.log('The file has been saved!');
                file.close();
            });
          }
        }else{
          //file empty 
          console.log('Not file is created!');
          console.log(pathFile);
          file.close();
        }
      } catch(err) {
        console.error(err);
        file.close();
      }
    });
  }catch(err){
    console.log(err);
    file.close();
  }
});

0

রিডলাইন-সিঙ্কটি ব্যবহার করা সবচেয়ে সহজ উপায়

এটি এক এক ইনপুট এবং আউট পুটে প্রক্রিয়া করে।

npm i readline-sync

উদাহরণ:

var firstPrompt = readlineSync.question('Are you sure want to initialize new db? This will drop whole database and create new one, Enter: (yes/no) ');

if (firstPrompt === 'yes') {
    console.log('--firstPrompt--', firstPrompt)
    startProcess()
} else if (firstPrompt === 'no') {
    var secondPrompt = readlineSync.question('Do you want to modify migration?, Enter: (yes/no) ');
    console.log('secondPrompt ', secondPrompt)
    startAnother()
} else {
    console.log('Invalid Input')
    process.exit(0)
}

আপনার সত্যই আপনার requireবক্তব্য অন্তর্ভুক্ত করা উচিত । এটি ছেড়ে দেওয়ার কোনও কারণ নেই।
solidstatejake
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.