有非同步I/O,必有非同步程式設計!今天來學習Node.js裡的非同步程式設計!
#曾經的單執行緒模型在同步I/O的影響下,由於I/O呼叫緩慢,在應用層面導致CPU與I/O無法重疊進行。為了照顧程式設計人員的閱讀思考習慣,同步I/O盛行了許多年。 【推薦學習:《nodejs 教學》】
#但有很大的效能問題!
Node利用JavaScript及其內部非同步程式庫,將非同步直接提升到業務層面。 Node帶來的最大特性莫過於基於事件驅動的非阻塞I/O模型。非阻塞I/O可以讓CPU與I/O並不互相依賴等待,讓資源有更好的利用。
#目的:讀取package.json 中main 欄位對應的檔案內容
Callback
使用回呼函數進行非同步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); }); });
問題:如何解決回調地獄?
Promise
Promise是具有四個狀態的有限狀態機,其中三個核心狀態為Pending(掛起),Fulfilled ( 完成)、Rejected(拒絕),以及還有一個未開始狀態
#詳細內容可以看我之前的博文Promise初探
#使用Promise,實作讀取package.json 中main 欄位對應的檔案內容
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); });
比較之前用Callback的解決方案,可以看出沒有嵌套的回調了,透過一系列的鍊式調用來處理非同步操作。
Callback 轉換為 Promise如何將 Callback 轉換成 Promise 形式?
可以使用Node自帶的工具函數util.promisify
可以自己實作一下: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);
await
await 函數使用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();
如果幾個任務是可以並行的,這樣寫就不太好了。這是,我們可以使用Promise.all來操作並行的任務
這裡也會有個小問題,我課後問老師了,這是老師的解答
【答】Promise.all 處理多個請求,當所有請求都成功的時候,resolve 一個數組回來,裡面是執行結果。如果有一個請求失敗就立刻 reject 那個錯誤來,所以這個地方我們不能使用 Promise.all 來實現。 Promise 有一個allSettled 方法,
developer.mozilla.org/en-US/docs/…Event
###發佈訂閱模式,Node.js 內建events 模組######例如HTTP ###server on('request')### 事件監聽################ ###########原文網址:https://juejin.cn/post/7005509871000895524#######作者:YK菌###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);登入後複製
更多程式相關知識,請造訪:程式設計影片! !
以上是深入了解Node.js中的非同步編程,分享四種解決方案的詳細內容。更多資訊請關注PHP中文網其他相關文章!