本課重點(diǎn):學(xué)習(xí)使用Node.js中的'readline'模塊實(shí)現(xiàn)終端的io交互功能豺鼻,并衍生到web中靜態(tài)頁面上的io交互功能實(shí)現(xiàn)沫勿。
Readline模塊
要使用此模塊挨约,需要require('readline');
Readline
程序允許逐行讀取一個(gè)流內(nèi)容(例如process.stdin)味混。
引入'readline'模塊:
var readline = require('readline');
需要注意的是你一旦調(diào)用了這個(gè)模塊,你的node程序?qū)⒉粫?huì)終止直到你關(guān)閉此接口诫惭。下面是如何讓你的程序正常退出的方法:
rl.close();
readline.createInterface(options)
創(chuàng)建一個(gè)readline的接口實(shí)例.
var rl = readline.createInterface(process.stdin, process.stdout);
接受一個(gè)Object類型參數(shù)翁锡,可傳遞以下幾個(gè)值:
- input 要監(jiān)聽的可讀流 (必需).
- output 要寫入 readline 的可寫流 (必須).
- completer 用于 Tab 自動(dòng)補(bǔ)全的可選函數(shù)。見下面使用的例子夕土。
- terminal如果希望 input 和 output流像 TTY 一樣對待馆衔,那么傳遞參數(shù) true,并且經(jīng)由 ANSI/VT100 轉(zhuǎn)碼怨绣。 默認(rèn)情況下檢查 isTTY是否在 output 流上實(shí)例化角溃。
通過用戶 completer函數(shù)給定了一個(gè)當(dāng)前行入口,并且期望返回一個(gè)包含兩個(gè)條目的數(shù)組:
1.一個(gè)匹配當(dāng)前輸入補(bǔ)全的字符串?dāng)?shù)組.
2.一個(gè)用于匹配的子字符串篮撑。
最終像這種形式:
[[substr1, substr2, ...], originalsubstring]
.
rl.setPrompt(prompt)
設(shè)置提示符减细,例如當(dāng)你在命令行運(yùn)行 node時(shí),你會(huì)看到 > 赢笨,這就是 node 的提示符未蝌。
rl.prompt([preserveCursor])
為用戶輸入準(zhǔn)備好readline,將現(xiàn)有的setPrompt選項(xiàng)放到新的一行茧妒,讓用戶有一個(gè)新的地方開始輸入萧吠。將preserveCursor設(shè)為true來防止光標(biāo)位置被重新設(shè)定成0。
如果暫停桐筏,也會(huì)使用 createInterface重置 input流纸型。
rl.question(query, callback)
預(yù)先提示指定的query,然后用戶應(yīng)答后觸發(fā)指定的callback九昧。 顯示指定的query給用戶后绊袋,當(dāng)用戶的應(yīng)答被輸入后,就觸發(fā)了指定的callback
如果暫停铸鹰,也會(huì)使用 createInterface重置 input流癌别。示例:
interface.question('What is your favorite food?', function(answer) {
console.log('Oh, so your favorite food is ' + answer);
});
rl.pause()
暫停 readline 的輸入流 (inputstream), 如果有需要稍后還可以恢復(fù)。
rl.resume()
恢復(fù) readline 的輸入流 (inputstream).
rl.close()
關(guān)閉接口實(shí)例 (Interfaceinstance), 放棄控制輸入輸出流蹋笼。"close" 事件會(huì)被觸發(fā)展姐。
rl.write(data, [key])
將 data寫入到 output流。key是一個(gè)代表鍵序列的對象剖毯;當(dāng)終端是一個(gè) TTY 時(shí)可用圾笨。
如果暫停,也會(huì)重置 input流逊谋。實(shí)例:
rl.write('Delete me!');
// 模仿 ctrl+u快捷鍵擂达,刪除之前所寫行
rl.write(null, {ctrl: true, name: 'u'});
事件說明
事件:'line'
在 input流接受了一個(gè) \n時(shí)觸發(fā),通常在用戶敲擊回車或者返回時(shí)接收胶滋。 這是一個(gè)監(jiān)聽用戶輸入的利器板鬓。
監(jiān)聽 line事件的示例:
rl.on('line', function (cmd) {
console.log('You just typed: '+cmd);
});
事件: 'resume'
不論何時(shí)悲敷,只要輸入流重新啟用就會(huì)觸發(fā)。示例:
rl.on('resume', function() {
console.log('Readline 恢復(fù).');
});
事件: 'close'
當(dāng) close()被調(diào)用時(shí)觸發(fā)俭令。
當(dāng) input流接收到"結(jié)束"事件時(shí)也會(huì)被觸發(fā). 一旦觸發(fā)后德,應(yīng)當(dāng)認(rèn)為Interface實(shí)例 "結(jié)束" . 例如, 當(dāng)input流接收到^D時(shí), 分別被認(rèn)為EOT.
當(dāng) input流接收到一個(gè) ^C時(shí),即使沒有 SIGINT監(jiān)聽器抄腔,也會(huì)觸發(fā)這個(gè)事件瓢湃,分別被稱為 SIGINT 。
事件:'SIGINT'
只要 input流 接收到^C就會(huì)被觸發(fā), 分別被認(rèn)為SIGINT.當(dāng)input流接收到SIGINT時(shí), 如果沒有 SIGINT事件監(jiān)聽器赫蛇,pause將會(huì)被觸發(fā).
監(jiān)聽 SIGINT信號(hào)的示例:
rl.on('SIGINT', function() {
rl.question('Are you sure you want to exit?', function(answer) {
if (answer.match(/^y(es)?$/i)) rl.pause();
});
});
事件:Event: 'SIGTSTP'
該功能不支持 windows 操作系統(tǒng)
只要input流接收到^Z時(shí)就被觸發(fā), 分別被認(rèn)為SIGTSTP. 當(dāng)input流接收到 SIGTSTP時(shí)绵患,如果沒有SIGTSTP
事件監(jiān)聽器 ,程序會(huì)被發(fā)送到后臺(tái) .
當(dāng)程序使用參數(shù) fg重啟,pause和 SIGCONT事件將會(huì)被觸發(fā)悟耘。 你可以使用兩者中任一事件來恢復(fù)流藏雏。
在程序被發(fā)送到后臺(tái)之前,如果流暫停作煌,pause和 SIGCONT事件將不會(huì)被觸發(fā)。
監(jiān)聽 SIGTSTP的示例:
rl.on('SIGTSTP', function() {
// 這將重載 SIGTSTP并防止程序轉(zhuǎn)到
// 后臺(tái).
console.log('Caught SIGTSTP.');
});
事件:'SIGCONT'
該功能不支持 windows 操作系統(tǒng)
一旦 input流中含有 ^Z并被發(fā)送到后臺(tái)就會(huì)觸發(fā),分別被認(rèn)為 SIGTSTP, 然后繼續(xù)執(zhí)行fg(1). 這一事件只有在流被發(fā)送后臺(tái)之前沒有暫停才會(huì)觸發(fā).
監(jiān)聽 SIGCONT的示例:
rl.on('SIGCONT', function() {
// `prompt` 將會(huì)自動(dòng)恢復(fù)流
rl.prompt();
});