首頁 > web前端 > js教程 > 主體

深入了解Node.js中的非同步編程,分享四種解決方案

青灯夜游
發布: 2021-09-14 10:15:03
轉載
2529 人瀏覽過

有非同步I/O,必有非同步程式設計!今天來學習Node.js裡的非同步程式設計!

深入了解Node.js中的非同步編程,分享四種解決方案

非同步程式設計概述

#曾經的單執行緒模型在同步I/O的影響下,由於I/O呼叫緩慢,在應用層面導致CPU與I/O無法重疊進行。為了照顧程式設計人員的閱讀思考習慣,同步I/O盛行了許多年。 【推薦學習:《nodejs 教學》】

深入了解Node.js中的非同步編程,分享四種解決方案

#但有很大的效能問題!

Node利用JavaScript及其內部非同步程式庫,將非同步直接提升到業務層面。 Node帶來的最大特性莫過於基於事件驅動的非阻塞I/O模型。非阻塞I/O可以讓CPU與I/O並不互相依賴等待,讓資源有更好的利用。

深入了解Node.js中的非同步編程,分享四種解決方案

非同步程式解決方案

#目的:讀取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);
  });
});
登入後複製

深入了解Node.js中的非同步編程,分享四種解決方案

問題:如何解決回調地獄?

Promise

Promise是具有四個狀態的有限狀態機,其中三個核心狀態為Pending(掛起),Fulfilled ( 完成)、Rejected(拒絕),以及還有一個未開始狀態

#詳細內容可以看我之前的博文Promise初探

深入了解Node.js中的非同步編程,分享四種解決方案

深入了解Node.js中的非同步編程,分享四種解決方案

#使用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.js中的非同步編程,分享四種解決方案可以使用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

深入了解Node.js中的非同步編程,分享四種解決方案

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();
登入後複製
await的語法寫起來就像同步編程一樣,這裡的操作是

串行操作,會一行一行的等待執行。

如果幾個任務是可以並行的,這樣寫就不太好了。這是,我們可以使用Promise.all來操作並行的任務

這裡也會有個小問題,我課後問老師了,這是老師的解答

【問】在非同步那塊,說到串列和並行,在並行處理那塊我有一個疑問。如果並行的場景要求:不管其他任務執行成功或失敗,每個非同步任務都要執行完,最後統一處理錯誤,那在用Promise.all來處理多個非同步任務時候,遇到第一個任務執行錯誤的時候就會返回,如何操作才能讓所有任務都執行完成,再統一處理錯誤呢

深入了解Node.js中的非同步編程,分享四種解決方案【答】Promise.all 處理多個請求,當所有請求都成功的時候,resolve 一個數組回來,裡面是執行結果。如果有一個請求失敗就立刻 reject 那個錯誤來,所以這個地方我們不能使用 Promise.all 來實現。 Promise 有一個allSettled 方法,

developer.mozilla.org/en-US/docs/…

深入了解Node.js中的非同步編程,分享四種解決方案

Event

###發佈訂閱模式,Node.js 內建events 模組######例如HTTP ###server on('request')### 事件監聽###
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);
登入後複製
############# ###########原文網址:https://juejin.cn/post/7005509871000895524#######作者:YK菌###

更多程式相關知識,請造訪:程式設計影片! !

以上是深入了解Node.js中的非同步編程,分享四種解決方案的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:掘金--YK菌
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!