溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Node.js中的異步編程的示例分析

發(fā)布時間:2021-09-10 10:39:30 來源:億速云 閱讀:172 作者:柒染 欄目:web開發(fā)

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.js中的異步編程的示例分析

但是有很大的性能問題!

Node利用JavaScript及其內(nèi)部異步庫,將異步直接提升到業(yè)務(wù)層面。Node帶來的最大特性莫過于基于事件驅(qū)動的非阻塞I/O模型。非阻塞I/O可以使CPU與I/O并不相互依賴等待,讓資源得到更好的利用。

Node.js中的異步編程的示例分析

異步編程解決方案

目的:讀取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ù)制代碼

Node.js中的異步編程的示例分析

問題:如何解決回調(diào)地獄?

Promise

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

詳細內(nèi)容可以看我之前的博文 Promise初探

Node.js中的異步編程的示例分析

使用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)用來處理異步操作。

Node.js中的異步編程的示例分析

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í)行。

Node.js中的異步編程的示例分析

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

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

Node.js中的異步編程的示例分析

【問】在異步那塊,說到串行和并行,在并行處理那塊我有一個疑問。如果并行的場景要求:不管其他任務(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ù)制代碼

Node.js中的異步編程的示例分析

Node.js中的異步編程的示例分析


看完上述內(nèi)容,你們掌握Node.js中的異步編程的示例分析的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責(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)容。

AI