Nodejs異步回呼的優雅處理方法_node.js
前言
Nodejs最大的亮點就在於事件驅動, 非阻塞I/O 模型,這使得Nodejs具有很強的並發處理能力,非常適合編寫網路應用。在Nodejs中大部分的I/O操作幾乎都是非同步的,也就是我們處理I/O的操作結果基本上都需要在回呼函數中處理,例如下面的這個讀取檔案內容的函數:
fs.readFile('/etc/passwd', function (err, data) {
if (err) throw err;
console.log(data);
});
那,我們讀取兩個文件,將這兩個文件的內容合併到一起處理怎麼辦呢?大多數接觸js不久的人可能會這麼幹:
fs.readFile('/etc/passwd', function (err, data) {
if (err) throw err;
fs.readFile('/etc/passwd2', function (err, data2) {
if (err) throw err;
// 在這裡處理data和data2的資料
});
});
那要是處理多個類似的場景,豈不是回呼函數一層層的嵌套啊,這就是大家常說的回調金字塔或回調地獄(http://callbackhell.com/)的問題,也是讓js小白最頭痛的問題。
這種層層嵌套的程式碼為開發帶來了許多問題,主要體現在:
1.程式碼可能性變差
2.調試困難
3.出現異常後難以排除
本文主要是介紹如何優雅的處理以上非同步回調問題。
初級方案:透過遞歸處理非同步回調
我們可以使用遞歸作為程式碼的執行控制工具。把需要執行的操作封裝到一個函數中,在回呼函數中透過遞歸呼叫控製程式碼的執行流程,廢話不多說,上個程式碼吧:
var fs = require('fs');
// 要處理的檔案清單
var files = ['file1', 'file2', 'file3'];
function parseFile () {
if (files.length == 0) {
return;
}
var file = files.shift();
fs.readFile(file, function (err, data) {
// 這裡處理檔案資料
parseFile(); // 處理完畢後,透過遞迴呼叫處理下一個檔案
});
}
// 開始處理
parseFile();
以上程式碼已依序處理陣列中的檔案為例,介紹了透過遞歸的方式控製程式碼的執行流程。
應用在一些簡單的場景中還是不錯的,例如:我們將一個數組中的數據,依次保存到資料庫中就可以採用這種方式。
透過遞歸的方式可以解決一些簡單的非同步回呼問題。不過對於處理複雜的非同步回呼還是顯得有些無能為力(如需要同步多個非同步操作的結果)。
華麗點:採用Async、Q、Promise等第三方函式庫處理非同步回調
為了更好的處理巢狀回呼的問題,可以考慮採用一些第三方專門處理非同步的函式庫,當然有能力的完全可以自己寫個非同步處理的輔助工具。
比較常用的處理非同步的函式庫有:async,q還有promise。從npmjs.org網站來看,async的火熱程度最高。以前用過async,確實也挺方便的,各種非同步處理的控制流程實現的也挺好。
我們將最初的同時讀取兩個檔案的程式碼使用async處理下,範例如下:
var async = require('async')
, fs = require('fs');
async.parallel([
function(callback){
fs.readFile('/etc/passwd', function (err, data) {
if (err) callback(err);
callback(null, data);
});
},
function(callback){
fs.readFile('/etc/passwd2', function (err, data2) {
if (err) callback(err);
callback(null, data2);
});
}
],
function(err, results){
// 在這裡處理data和data2的資料,每個檔案的內容從results中取得
});
透過async模組,可以很好的控制非同步的執行流程了,也算是解決了層層回呼的問題,程式碼比以前算是清晰了些,不過依舊還是離不開回呼函數。
想想如果能夠在不使用回呼函數的情況下,處理異步,豈不是很爽,接下來,我們談談使用ES6的新特性來實現這一目標。
優雅點:擁抱ES6,取代回調函數,解決回調地獄問題
話說EcmaScript Harmony (ES6)為js引入了不少新特性,對ES6不太了解的同學,可以自行百度一下。
在nodejs中使用ES6的新特性,需要用v0.11.x以上的版本才行。
本文介紹的是使用Generator特性取代回呼函數,對Generator不了解?可以看看這裡。
這裡用到了co和thunkify兩個模組,大家使用npm install指令安裝之。
還是以本文剛開始提到的問題為例,使用generator特性的實例程式碼如下:
var fs = require('fs')
, co = require('co')
, thunkify = require('thunkify');
var readFile = thunkify(fs.readFile);
co(function *() {
var test1 = yield readFile('test1.txt');
var test2 = yield readFile('test2.txt');
var test = test1.toString() test2.toString();
console.log(test);
})();
處理程式碼中的異常也是很簡單的,只要這樣就OK了:
try {
var test1 = yield readFile('test1.txt');
} catch (e) {
// 在這裡處理異常
}
這種程式碼是不是優雅很多了?像寫同步程式碼一樣處理異步,是不是很酷!
nodejs領域中進行Web開發,最火的框架莫過於express了,值得一提的是express的核心成員TJ大神有領導了一個新的Web框架——koa,宣稱是下一代的Web開發框架,koa真是藉助了ES6的generator這個特性,讓我們在開發Web系統的時候避免陷入層層的回調用。
總結
引用fibjs專案宣傳的一句話:Less Callback, More Girls - 更少回調, 更多女孩

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Node.js 是一種伺服器端 JavaScript 執行時,而 Vue.js 是一個客戶端 JavaScript 框架,用於建立互動式使用者介面。 Node.js 用於伺服器端開發,如後端服務 API 開發和資料處理,而 Vue.js 用於用戶端開發,如單一頁面應用程式和響應式使用者介面。

要連接 MySQL 資料庫,需要遵循以下步驟:安裝 mysql2 驅動程式。使用 mysql2.createConnection() 建立連接對象,其中包含主機位址、連接埠、使用者名稱、密碼和資料庫名稱。使用 connection.query() 執行查詢。最後使用 connection.end() 結束連線。

Node.js 中存在以下全域變數:全域物件:global核心模組:process、console、require執行階段環境變數:__dirname、__filename、__line、__column常數:undefined、null、NaN、Infinity、-Infinity

Node.js 安裝目錄中有兩個與 npm 相關的文件:npm 和 npm.cmd,區別如下:擴展名不同:npm 是可執行文件,npm.cmd 是命令視窗快捷方式。 Windows 使用者:npm.cmd 可以在命令提示字元中使用,npm 只能從命令列執行。相容性:npm.cmd 特定於 Windows 系統,npm 跨平台可用。使用建議:Windows 使用者使用 npm.cmd,其他作業系統使用 npm。

Node.js 和 Java 的主要差異在於設計和特性:事件驅動與執行緒驅動:Node.js 基於事件驅動,Java 基於執行緒驅動。單執行緒與多執行緒:Node.js 使用單執行緒事件循環,Java 使用多執行緒架構。執行時間環境:Node.js 在 V8 JavaScript 引擎上運行,而 Java 在 JVM 上運行。語法:Node.js 使用 JavaScript 語法,而 Java 使用 Java 語法。用途:Node.js 適用於 I/O 密集型任務,而 Java 適用於大型企業應用程式。

Node.js 和 Java 在 Web 開發中各有優劣,因此選擇取決於專案需求。 Node.js 擅長即時應用程式、快速開發和微服務架構,而 Java 則在企業級支援、效能和安全性方面佔優。
