假設一個商業場景:
透過rss地址,取得rss並儲存於文件,rss地址保存於文件中。
完成該場景的業務需要完成3個任務:
1.從檔案讀取rss位址。
2.取得rss。
3.儲存於文件。
最後將這三個任務整合。
準備:
存放rss地址的文件,address.txt。
http://programmer.csdn.net/rss_programmer.html
任務1:
讀取rss位址檔案的內容並透過callback回傳。
var getRssAddress = function(path, callback) {
fs.readFile(path, {encoding: 'utf8'}, function (err, data) {
callback(err, data);
});
}
任務2:
透過rss位址get到rss,並透過callback回傳錯誤或資料。
var getRss = function(url, callback) {
var data = '';
http.get(url, function(res) {
res.on('data', function(chrunk) {
data = chrunk;
});
res.on('end', function() {
callback(null, data);
});
}).on('error', function(err) {
callback(err, null);
});
}
任務3:
將rss儲存於檔案並透過callback回傳錯誤。
var saveRss = function(data, callback) {
fs.writeFile('rss.txt', data, 'utf8', function(err) {
callback(err);
});
}
整合:
getRssAddress('address.txt', function(err, data) {
if(err) {
console.log(err);
return;
}
getRss(data, function(err, data) {
if(err) {
console.log(err);
return;
}
saveRss(data, function(err) {
if(err) console.log(err);
});
});
});
上面的程式碼是全非同步處理,使用最常見的callback處理非同步邏輯的返回,好處是標準寫法,大家都能容易接受;壞處是耦合性太強,處理異常麻煩,程式碼不直觀,特別是處理業務邏輯複雜和處理任務多的場景,層層的callback會讓人眼冒金星,程式碼難以維護。
Promise/A規範的實作之一when.js正是針對這樣的問題域。
讓我們來看看改造後的程式碼。
任務1:
var getRssAddress = function(path) {
var deferred = when.defer();
fs.readFile(path, {encoding: 'utf8'}, function (err, data) {
if (err) deferred.reject(err);
deferred.resolve(data);
});
return deferred.promise;
}
任務2:
var getRss = 函數(url) {
var deferred = when.defer();
var data = '';
http.get(url, 函數(res) {
res.on('data', function(chrunk) {
資料 = 區塊;
});
res.on('end', function() {
deferred.resolve(資料);
});
}).on('錯誤', 函數(err) {
deferred.reject(err);
});
返回 deferred.promise;
}
任務3:
var saveRss = 函數(data) {
var deferred = when.defer();
fs.writeFile('rss.txt', data, 'utf8', function(err) {
if(err) deferred.reject(err);
deferred.resolve();
});
回 deferred.promise;
}
整合:
getRssAddress('address.txt')
.then(getRss)
.then(saveRss)
.catch(函數(錯誤) {
console.log(錯誤);
});
解釋:
promise/A規範定義的「Deferred/Promise」模型就是「發布/訂閱者」模型,透過Deferred物件發布事件,可以是完成resolve事件,或是失敗reject事件;透過Promise物件回覆完成或失敗的訂閱。
在Promises/A規格中,每個任務都有透明狀態:預設(pending)、完成(fulfilled)、失敗(rejected)。
1.預設狀態可以單向轉移到完成,這個過程叫做resolve,對應的方法是deferred.resolve(promiseOrValue);
2.預設狀態還可以單向轉移到失敗,這個過程叫做reject,對應的方法是deferred.reject(reason);
3.狀態預設時,也可以透過deferred.notify(update)來宣告任務執行訊息,如執行進度;
4.狀態的轉移是瞬時的,一旦任務由初始的pending轉為其他狀態,就會進入到下一個任務的執行過程中。
按照上面的程式碼。
透過when.defer定義一個deferred物件。
var deferred = when.defer();
非同步資料獲取成功後,發布一個完成事件。
deferred.resolve(數據);
非同步資料獲取失敗後,發布一個失敗事件。
deferred.reject(err);
並返回Promise物件作為訂閱使用。
返回 deferred.promise;
訂閱是透過Promise物件的then方法進行完成/失敗/通知的訂閱。
getRssAddress('address.txt')
.then(getRss)
那麼有三個參數,分別是onFulfilled、onRejected、onProgress
promise.then(onFulfilled, onRejected, onProgress)
上一個任務被resolve(data),onFulfilled函數就會被觸發,data作為它的參數。
上一個任務被拒絕(原因),那麼onRejected就會被觸發,收到原因。
任何時候,onFulfilled和onRejected都只有其中一個可以被觸發,並且只觸發一次。
對於處理異常,when.js也提供了極為方便的方法,然後可以提交錯誤,多個任務串列執行時,我們可以只在最後一個then定義onRejected。也可以在最後一個then的後面呼叫catch函數捕捉任何一個任務的異常。
這樣寫法就簡單明了。
getRssAddress('address.txt')
.then(getRss)
.then(saveRss)
.catch(函數(錯誤) {
console.log(錯誤);
});
Promise 為非同步程式設計帶來了巨大的方便,可以讓我們專注於單一任務的實現而不是瀑布金字塔厄運,除了以上程式碼的基本使用,when.js 提供的功能顯然不止本文提到的這些,具體參考官方API。

Vercel是什么?本篇文章带大家了解一下Vercel,并介绍一下在Vercel中部署 Node 服务的方法,希望对大家有所帮助!

gm是基于node.js的图片处理插件,它封装了图片处理工具GraphicsMagick(GM)和ImageMagick(IM),可使用spawn的方式调用。gm插件不是node默认安装的,需执行“npm install gm -S”进行安装才可使用。

本篇文章带大家详解package.json和package-lock.json文件,希望对大家有所帮助!

本篇文章给大家分享一个Nodejs web框架:Fastify,简单介绍一下Fastify支持的特性、Fastify支持的插件以及Fastify的使用方法,希望对大家有所帮助!

如何用pkg打包nodejs可执行文件?下面本篇文章给大家介绍一下使用pkg将Node.js项目打包为可执行文件的方法,希望对大家有所帮助!

node怎么爬取数据?下面本篇文章给大家分享一个node爬虫实例,聊聊利用node抓取小说章节的方法,希望对大家有所帮助!

本篇文章给大家分享一个Node实战,介绍一下使用Node.js和adb怎么开发一个手机备份小工具,希望对大家有所帮助!

先介绍node.js的安装,再介绍使用node.js构建一个简单的web服务器,最后通过一个简单的示例,演示网页与服务器之间的数据交互的实现。


熱AI工具

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

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

MinGW - Minimalist GNU for Windows
這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

Dreamweaver Mac版
視覺化網頁開發工具

Safe Exam Browser
Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

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

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