您好,登錄后才能下訂單哦!
Node.js中的異步編程的示例分析,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
異步編程概述
曾經(jīng)的單線程模型在同步I/O的影響下,由于I/O調(diào)用緩慢,在應(yīng)用層面導(dǎo)致CPU與I/O無法重疊進行。為了照顧編程人員的閱讀思維習(xí)慣,同步I/O盛行了很多年。
但是有很大的性能問題!
Node利用JavaScript及其內(nèi)部異步庫,將異步直接提升到業(yè)務(wù)層面。Node帶來的最大特性莫過于基于事件驅(qū)動的非阻塞I/O模型。非阻塞I/O可以使CPU與I/O并不相互依賴等待,讓資源得到更好的利用。
目的:讀取package.json 中main 字段對應(yīng)的文件內(nèi)容
Callback
使用回調(diào)函數(shù)進行異步I/O的操作
const fs = require("fs"); fs.readFile("./package.json", { encoding: "utf-8" }, (err, data) => { if (err) throw err; const { main } = JSON.parse(data); fs.readFile(main, { encoding: "utf-8" }, (err, data) => { if (err) throw err; console.log(data); }); });復(fù)制代碼
問題:如何解決回調(diào)地獄?
Promise
Promise是一個具有四個狀態(tài)的有限狀態(tài)機,其中三個核心狀態(tài)為Pending(掛起),F(xiàn)ulfilled( 完成)、Rejected(拒絕),以及還有一個未開始狀態(tài)
詳細內(nèi)容可以看我之前的博文 Promise初探
使用Promise,實現(xiàn)讀取 package.json 中 main 字段對應(yīng)的文件內(nèi)容
const { readFile } = require("fs/promises"); readFile("./package.json", { encoding: "utf-8" }) .then((res) => { return JSON.parse(res); }) .then((data) => { return readFile(data.main, { encoding: "utf-8" }); }) .then((res) => { console.log(res); });復(fù)制代碼
對比之前用Callback的解決方案,可以看出沒有嵌套的回調(diào)了,通過一系列的鏈?zhǔn)秸{(diào)用來處理異步操作。
Callback 轉(zhuǎn)為 Promise
如何將 Callback 轉(zhuǎn)為 Promise 形式?
可以使用Node自帶的工具函數(shù) util.promisify
可以自己實現(xiàn)一下:
function promisify(fn, receiver) { return (...args) => { return new Promise((resolve, reject) => { fn.apply(receiver, [ ...args, (err, res) => { return err ? reject(err) : resolve(res); }, ]); }); }; }const readFilePromise = promisify(fs.readFile, fs);復(fù)制代碼
await
await 函數(shù)使用 try catch 捕獲異常(注意并行處理)
const { readFile } = require("fs/promises");const start = async () => { const { main } = JSON.parse( await readFile("./package.json", { encoding: "utf-8" }) ); const data = await readFile(main, { encoding: "utf-8" }); console.log(data); }; start();復(fù)制代碼
await的語法寫起來就像同步編程一樣,這里的操作是串行操作,會一行一行的等待執(zhí)行。
如果幾個任務(wù)是可以并行的,這樣寫就不太好了。這是,我們可以使用Promise.all來操作并行的任務(wù)
這里也會有個小問題,我課后問老師了,這是老師的解答
【問】在異步那塊,說到串行和并行,在并行處理那塊我有一個疑問。如果并行的場景要求:不管其他任務(wù)執(zhí)行成功還是失敗,每個異步任務(wù)都要執(zhí)行完,最后統(tǒng)一處理錯誤,那在用Promise.all來處理多個異步任務(wù)時候,遇到第一個任務(wù)執(zhí)行錯誤的時候就會返回,如何操作才能讓所有任務(wù)都執(zhí)行完成,再統(tǒng)一處理錯誤呢
【答】Promise.all 處理多個請求,當(dāng)所有請求都成功的時候,resolve 一個數(shù)組回來,里面是執(zhí)行結(jié)果。如果有一個請求失敗就立刻 reject 那個錯誤來,所以這個地方我們不能使用 Promise.all 來實現(xiàn)。Promise 有一個 allSettled 方法,developer.mozilla.org/en-US/docs/…
Event
發(fā)布訂閱模式,Node.js 內(nèi)置events 模塊
比如HTTP server on('request')
事件監(jiān)聽
const EventEmitter = require("events");class MyEmitter extends EventEmitter {}const myEmitter = new MyEmitter(); myEmitter.on("event", () => { console.log("an event occurred!"); }); myEmitter.emit("event");const http = require("http");const server = http.createServer((req, res) => { res.end("hello!!! this is YK!!!"); }); server.on("request", (req, res) => { console.log(req.url); }); server.listen(3000);復(fù)制代碼
看完上述內(nèi)容,你們掌握Node.js中的異步編程的示例分析的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。