本篇文章給大家分享的是有關(guān)javascript開(kāi)發(fā)后端程序的神器nodejs的使用方法,小編覺(jué)得挺實(shí)用的,因此分享給大家學(xué)習(xí),希望大家閱讀完這篇文章后可以有所收獲,話不多說(shuō),跟著小編一起來(lái)看看吧。
成都創(chuàng)新互聯(lián)2013年至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元張掖做網(wǎng)站,已為上家服務(wù),為張掖各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18980820575
javascript雖然一直都可以做服務(wù)端編程語(yǔ)言,但是它更多的是以客戶端編程語(yǔ)言來(lái)展示在世人面前的。也許javascript自己都忘記了還可以做服務(wù)器端編程,直到2009年nodejs的橫空出世。
javascript作為一門解釋性語(yǔ)言,是不需要像C或者C++那樣進(jìn)行編譯的。但是在早期的時(shí)候,javascript引擎的執(zhí)行效率是比較低的,所以導(dǎo)致javascript只能做做dom操作。
隨著ajax的興起和現(xiàn)代web2.0的技術(shù)的發(fā)展,主流瀏覽器開(kāi)發(fā)商盡可能的提升javascript的執(zhí)行效率,最后Chrome V8出現(xiàn)了,Chrome V8是 Chromium 項(xiàng)目開(kāi)源的 JavaScript 引擎,使得javascript的執(zhí)行效率得到了極大的提升。
nodejs借著V8浴火重生了。
nodejs從一誕生就獲得了極大的關(guān)注。比較javascript的開(kāi)發(fā)者還是非常非常多的。而且一門語(yǔ)言可以通用前后端是多么的有吸引力。
nodejs從2009年發(fā)展到2020年的nodejs 14,經(jīng)歷了11年的歷史,和它的先輩javascript相比還是很年輕,但是因?yàn)槠溟_(kāi)放性和包容性,nodejs在以一個(gè)非常快的速度向前發(fā)展。
nodejs借助于V8引擎和一組異步的 I/O 原生功能,極大的提升了nodejs的處理效率。
異步IO我們大家應(yīng)該都很清楚,和同步IO相比,線程不用阻塞,可以去處理其他更有意義的事情。只是在響應(yīng)返回的時(shí)候恢復(fù)操作,所以不會(huì)浪費(fèi)CPU時(shí)間。
我們簡(jiǎn)單看一下nodejs的IO模型:
一個(gè)好的語(yǔ)言需要有良好的生態(tài)系統(tǒng)相配合,因?yàn)檎Z(yǔ)言本身只能提供最基本的一些操作,我們還需要第三方系統(tǒng)來(lái)豐富這個(gè)語(yǔ)言的生態(tài)。
而nodejs的npm倉(cāng)庫(kù),托管著全球最大的開(kāi)源庫(kù)生態(tài)系統(tǒng)。
基本上使用nodejs你可以實(shí)現(xiàn)絕大多數(shù)需要的功能。
nodejs的另外一個(gè)特點(diǎn)就是簡(jiǎn)單,考慮一下我們最常用的web應(yīng)用,如果用java來(lái)寫,非常麻煩,你還需要一個(gè)web服務(wù)器。
在nodejs中,一切都是那么的簡(jiǎn)單:
const http = require('http')const hostname = '127.0.0.1'const port = 3000const server = http.createServer((req, res) => { res.statusCode = 200 res.setHeader('Content-Type', 'text/plain') res.end('welcome to www.flydean.com\n')})server.listen(port, hostname, () => { console.log(`please visit http://${hostname}:${port}/`)})
上面的代碼就創(chuàng)建了一個(gè)web服務(wù),監(jiān)聽(tīng)在3000端口,
我們首先引入了http模塊,用來(lái)進(jìn)行http處理。
接著使用http 的 createServer() 方法會(huì)創(chuàng)建新的 HTTP 服務(wù)器并返回它。
在createServer方法內(nèi)部,我們可以設(shè)定要返回的對(duì)象。
最后啟用server.listen功能,來(lái)監(jiān)聽(tīng)特定的端口和服務(wù)器,當(dāng)服務(wù)就緒之后,會(huì)調(diào)用后面的回調(diào)函數(shù),執(zhí)行特定的命令。
每當(dāng)接收到新的請(qǐng)求的時(shí)候,就會(huì)觸發(fā)request事件,request事件可以傳遞兩個(gè)參數(shù):
request 是一個(gè)http.IncomingMessage對(duì)象,提供了請(qǐng)求的詳細(xì)信息。
response 是一個(gè)http.ServerResponse對(duì)象,用于返回?cái)?shù)據(jù)給調(diào)用方。
在上面的例子中,我們并沒(méi)有使用request,而是使用response直接構(gòu)建了返回的對(duì)象。
我們?cè)O(shè)置了statusCode和header,最后使用end來(lái)關(guān)閉響應(yīng)。
這就是一個(gè)簡(jiǎn)單使用的nodejs程序。
nodejs作為js的一種,是一種解釋性語(yǔ)言,一般解釋性語(yǔ)言都有兩種運(yùn)行方式。
一種是直接運(yùn)行,一種是開(kāi)啟一個(gè)解釋性的環(huán)境,在其中運(yùn)行,nodejs也不例外。
直接運(yùn)行很簡(jiǎn)單,我們寫好nodejs的程序之后,比如app.js,直接這樣運(yùn)行:
node app.js
如果直接執(zhí)行node命令,就會(huì)開(kāi)啟REPL模式:
nodeWelcome to Node.js v12.13.1.Type ".help" for more information.>
REPL 也被稱為運(yùn)行評(píng)估打印循環(huán),是一種編程語(yǔ)言環(huán)境(主要是控制臺(tái)窗口),它使用單個(gè)表達(dá)式作為用戶輸入,并在執(zhí)行后將結(jié)果返回到控制臺(tái)。
REPL有什么作用呢?
第一,我們可以直接在REPL中運(yùn)行某些測(cè)試方法,已驗(yàn)證輸出結(jié)果。
比如這樣:
> console.log('www.flydean.com');www.flydean.com
除此之外REPL還有一些更加有用的功能,我們知道JS中一切皆對(duì)象,比如上面我們提到的http對(duì)象,如果我們想知道http對(duì)象的大概結(jié)構(gòu)怎么辦呢?
直接在REPL環(huán)境中輸入http即可:
> http{ _connectionListener: [Function: connectionListener], METHODS: [ 'ACL', 'BIND', 'CHECKOUT', 'CONNECT', 'COPY', 'DELETE', 'GET', 'HEAD', 'LINK', 'LOCK', 'M-SEARCH', 'MERGE', 'MKACTIVITY', 'MKCALENDAR', 'MKCOL', 'MOVE', 'NOTIFY', 'OPTIONS', 'PATCH', 'POST', 'PROPFIND', 'PROPPATCH', 'PURGE', 'PUT', 'REBIND', 'REPORT', 'SEARCH', 'SOURCE', 'SUBSCRIBE', 'TRACE', 'UNBIND', 'UNLINK', 'UNLOCK', 'UNSUBSCRIBE' ], STATUS_CODES: { '100': 'Continue', '101': 'Switching Protocols', '102': 'Processing', '103': 'Early Hints', '200': 'OK', '201': 'Created', '202': 'Accepted', '203': 'Non-Authoritative Information', '204': 'No Content', '205': 'Reset Content', '206': 'Partial Content', '207': 'Multi-Status', '208': 'Already Reported', '226': 'IM Used', '300': 'Multiple Choices', '301': 'Moved Permanently', '302': 'Found', '303': 'See Other', '304': 'Not Modified', '305': 'Use Proxy', '307': 'Temporary Redirect', '308': 'Permanent Redirect', '400': 'Bad Request', '401': 'Unauthorized', '402': 'Payment Required', '403': 'Forbidden', '404': 'Not Found', '405': 'Method Not Allowed', '406': 'Not Acceptable', '407': 'Proxy Authentication Required', '408': 'Request Timeout', '409': 'Conflict', '410': 'Gone', '411': 'Length Required', '412': 'Precondition Failed', '413': 'Payload Too Large', '414': 'URI Too Long', '415': 'Unsupported Media Type', '416': 'Range Not Satisfiable', '417': 'Expectation Failed', '418': "I'm a Teapot", '421': 'Misdirected Request', '422': 'Unprocessable Entity', '423': 'Locked', '424': 'Failed Dependency', '425': 'Unordered Collection', '426': 'Upgrade Required', '428': 'Precondition Required', '429': 'Too Many Requests', '431': 'Request Header Fields Too Large', '451': 'Unavailable For Legal Reasons', '500': 'Internal Server Error', '501': 'Not Implemented', '502': 'Bad Gateway', '503': 'Service Unavailable', '504': 'Gateway Timeout', '505': 'HTTP Version Not Supported', '506': 'Variant Also Negotiates', '507': 'Insufficient Storage', '508': 'Loop Detected', '509': 'Bandwidth Limit Exceeded', '510': 'Not Extended', '511': 'Network Authentication Required' }, Agent: [Function: Agent] { defaultMaxSockets: Infinity }, ClientRequest: [Function: ClientRequest], IncomingMessage: [Function: IncomingMessage], OutgoingMessage: [Function: OutgoingMessage], Server: [Function: Server], ServerResponse: [Function: ServerResponse], createServer: [Function: createServer], get: [Function: get], request: [Function: request], maxHeaderSize: [Getter], globalAgent: [Getter/Setter]}
直接輸出了http對(duì)象的簡(jiǎn)潔結(jié)構(gòu),我們還可以使用tab按鈕來(lái)自動(dòng)補(bǔ)全http的方法:
> http.http.__defineGetter__ http.__defineSetter__ http.__lookupGetter__ http.__lookupSetter__ http.__proto__ http.constructorhttp.hasOwnProperty http.isPrototypeOf http.propertyIsEnumerable http.toLocaleString http.toString http.valueOfhttp.Agent http.ClientRequest http.IncomingMessage http.METHODS http.OutgoingMessage http.STATUS_CODEShttp.Server http.ServerResponse http._connectionListener http.createServer http.get http.globalAgenthttp.maxHeaderSize http.request
PREL還支持一些特定的點(diǎn)操作:
> .help.break Sometimes you get stuck, this gets you out.clear Alias for .break.editor Enter editor mode.exit Exit the repl.help Print this help message.load Load JS from a file into the REPL session.save Save all evaluated commands in this REPL session to a file
PERL還有一個(gè)特殊變量 _ ,如果在某些代碼之后輸入 _,則會(huì)打印最后一次操作的結(jié)果。
process 對(duì)象是一個(gè)全局變量,提供了有關(guān)當(dāng)前 Node.js 進(jìn)程的信息并對(duì)其進(jìn)行控制。作為全局變量,它始終可供 Node.js 應(yīng)用程序使用,無(wú)需使用 require()。它也可以使用 require() 顯式地訪問(wèn)。
因?yàn)閜rocess代表的是nodejs的進(jìn)程信息,所以可以處理進(jìn)程終止,讀取環(huán)境變量,接收命令行參數(shù)等作用。
先看一下怎么使用process來(lái)終止進(jìn)程:
process.exit(0)
0表示正常退出,當(dāng)然,我們可以傳入不同的退出碼,表示不同的含義。
正常情況下,如果沒(méi)有異步操作正在等待,那么 Node.js 會(huì)以狀態(tài)碼 0 退出,其他情況下,會(huì)用如下的狀態(tài)碼:
1 未捕獲異常 – 一個(gè)未被捕獲的異常, 并且沒(méi)被 domain 或 ‘uncaughtException’ 事件處理器處理。
2 – 未被使用 (Bash 為防內(nèi)部濫用而保留)
3 內(nèi)部的 JavaScript 解析錯(cuò)誤 – Node.js 內(nèi)部的 JavaScript 源代碼在引導(dǎo)進(jìn)程中導(dǎo)致了一個(gè)語(yǔ)法解析錯(cuò)誤。一般只會(huì)在開(kāi)發(fā) Node.js 本身的時(shí)候出現(xiàn)。
4 內(nèi)部的 JavaScript 執(zhí)行失敗 – 引導(dǎo)進(jìn)程執(zhí)行 Node.js 內(nèi)部的 JavaScript 源代碼時(shí),返回函數(shù)值失敗。一般只會(huì)在開(kāi)發(fā) Node.js 本身的時(shí)候出現(xiàn)。
5 致命錯(cuò)誤 – 在 V8 中有一個(gè)致命的錯(cuò)誤。比較典型的是以 FATALERROR 為前綴從 stderr 打印出來(lái)的消息。
6 非函數(shù)的內(nèi)部異常處理 – 發(fā)生了一個(gè)內(nèi)部異常,但是內(nèi)部異常處理函數(shù)被設(shè)置成了一個(gè)非函數(shù),或者不能被調(diào)用。
7 內(nèi)部異常處理運(yùn)行時(shí)失敗 – 有一個(gè)不能被捕獲的異常,在試圖處理這個(gè)異常時(shí),處理函數(shù)本身拋出了一個(gè)錯(cuò)誤。比如, 如果一個(gè) ‘uncaughtException’ 或者 domain.on(‘error’) 處理函數(shù)拋出了一個(gè)錯(cuò)誤。
8 – 未被使用,在之前版本的 Node.js, 退出碼 8 有時(shí)候表示一個(gè)未被捕獲的異常。
9 – 不可用參數(shù) – 某個(gè)未知選項(xiàng)沒(méi)有確定,或者沒(méi)給必需要的選項(xiàng)填值。
10 內(nèi)部的 JavaScript 運(yùn)行時(shí)失敗 – 調(diào)用引導(dǎo)函數(shù)時(shí),引導(dǎo)進(jìn)程執(zhí)行 Node.js 內(nèi)部的 JavaScript 源代碼拋出錯(cuò)誤。一般只會(huì)在開(kāi)發(fā) Node.js 本身的時(shí)候出現(xiàn)。
12 不可用的調(diào)試參數(shù)
13 未完成的Top-Level Await: await傳入的Promise一直沒(méi)有調(diào)用resolve方法
128 退出信號(hào) – 如果 Node.js 接收到致命信號(hào), 諸如 SIGKILL 或 SIGHUP,那么它的退出代碼將是 128 加上信號(hào)的碼值。例如,信號(hào) SIGABRT 的值為 6,因此預(yù)期的退出代碼將為 128 + 6 或 134。
我們可以通過(guò)process的on方法,來(lái)監(jiān)聽(tīng)信號(hào)事件:
process.on('SIGTERM', () => { server.close(() => { console.log('進(jìn)程已終止') })})
什么是信號(hào)?信號(hào)是一個(gè) POSIX 內(nèi)部通信系統(tǒng):發(fā)送通知給進(jìn)程,以告知其發(fā)生的事件。
或者我們可以從程序內(nèi)部發(fā)送這個(gè)信號(hào):
process.kill(process.pid, 'SIGTERM')
因?yàn)閜rocess進(jìn)程是和外部環(huán)境打交道的,process提供了env屬性,該屬性承載了在啟動(dòng)進(jìn)程時(shí)設(shè)置的所有環(huán)境變量。
默認(rèn)情況下,env中的NODE_ENV被設(shè)置為development。
process.env.NODE_ENV // "development"
我們可以通過(guò)修改這個(gè)環(huán)境變量,來(lái)切換nodejs的不同運(yùn)行環(huán)境。
process提供了argv來(lái)接收外部參數(shù)。
比如:
node app.js joe
argv是一個(gè)包含所有命令行調(diào)用參數(shù)的數(shù)組。
上面的例子中,第一個(gè)參數(shù)是 node 命令的完整路徑。第二個(gè)參數(shù)是正被執(zhí)行的文件的完整路徑。所有其他的參數(shù)從第三個(gè)位置開(kāi)始。
要想獲取joe,我們可以這樣做:
const args = process.argv.slice(2)args[0]
如果是key=value的情況,我們可以這樣傳參數(shù),并且使用minimist 庫(kù)來(lái)處理參數(shù):
node app.js --name=joeconst args = require('minimist')(process.argv.slice(2))args['name'] //joe
從 nodejs7開(kāi)始,nodejs提供了readline模塊,可以從process.stdin獲取輸入:
const readline = require('readline').createInterface({ input: process.stdin, output: process.stdout})readline.question(`how are you?`, answer => { console.log(`${answer}!`) readline.close()})
如果需要更加復(fù)雜的操作,則可以使用Inquirer.js:
const inquirer = require('inquirer')var questions = [ { type: 'input', name: 'hello', message: "how are you?" }]inquirer.prompt(questions).then(answers => { console.log(`${answers['hello']}!`)})
nodejs擁有內(nèi)置的模塊系統(tǒng),當(dāng)我們需要使用其他lib提供的功能時(shí)候,我們可以使用require來(lái)引入其他lib公開(kāi)的模塊。
但是前提是該lib需要公開(kāi),也就是exports對(duì)應(yīng)的模塊出來(lái)。
nodejs的對(duì)象導(dǎo)出有兩種方式module.exports和將對(duì)象添加為 exports 的屬性。
先看第一種方式,square 模塊定義在 square.js 中:
module.exports = class Square { constructor(width) { this.width = width; } area() { return this.width ** 2; }};
下面的例子中, bar.js 使用了導(dǎo)出 Square 類的 square 模塊:
const Square = require('./square.js');const mySquare = new Square(2);console.log(`mySquare 的面積是 ${mySquare.area()}`);
再看第二種方式,定義一個(gè)circle.js:
const { PI } = Math;exports.area = (r) => PI * r ** 2;exports.circumference = (r) => 2 * PI * r;
使用:
const circle = require('./circle.js');console.log(`半徑為 4 的圓的面積是 ${circle.area(4)}`);
兩者都可以導(dǎo)出特定的模塊,但是module.exports只會(huì)導(dǎo)出特定的對(duì)象,而exports是將對(duì)象添加為exports的屬性,我們還需要根據(jù)屬性名稱來(lái)查找對(duì)象的屬性。
除了我們上面提到的http,process, nodejs還提供了很多其他非常有用的API :
除了基本的nodejs之外,nodejs還有非常多優(yōu)秀的框架,借助這些框架我們可以是nodejs程序的搭建更加容易和強(qiáng)大。
像AdonisJs,express,koa,Socket.io等等。
以上就是javascript開(kāi)發(fā)后端程序的神器nodejs的使用方法,小編相信有部分知識(shí)點(diǎn)可能是我們?nèi)粘9ぷ鲿?huì)見(jiàn)到或用到的。希望你能通過(guò)這篇文章學(xué)到更多知識(shí)。更多詳情敬請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
網(wǎng)站標(biāo)題:javascript開(kāi)發(fā)后端程序的神器nodejs的使用方法
文章分享:http://aaarwkj.com/article28/gdepjp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、自適應(yīng)網(wǎng)站、網(wǎng)站改版、、小程序開(kāi)發(fā)、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)