首頁 web前端 js教程 node.js下when.js 的非同步程式設計實作_node.js

node.js下when.js 的非同步程式設計實作_node.js

May 16, 2016 pm 04:29 PM
node.js 非同步程式設計

假設一個商業場景:

透過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。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

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

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

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

如何用 C++ 函數實作非同步程式設計? 如何用 C++ 函數實作非同步程式設計? Apr 27, 2024 pm 09:09 PM

摘要:C++中的非同步程式設計允許多工處理,無需等待耗時操作。使用函數指標建立指向函數的指標。回調函數在非同步操作完成時被呼叫。 boost::asio等函式庫提供非同步程式支援。實戰案例示範如何使用函數指標和boost::asio實現非同步網路請求。

PHP中如何使用ReactPHP進行非同步編程 PHP中如何使用ReactPHP進行非同步編程 Jun 27, 2023 am 09:14 AM

隨著Web應用程式變得越來越複雜,程式設計師不得不採用非同步程式來處理大量請求和I/O操作。 PHP:HypertextPreprocessor也不例外。為了滿足這項需求,ReactPHP已成為目前最受歡迎的PHP非同步程式設計框架之一。在本文中,將討論如何在PHP中使用ReactPHP進行非同步程式設計。 1.ReactPHP簡介ReactPHP是基於事件驅動編程

JavaScript函數非同步程式設計:處理複雜任務的必備技巧 JavaScript函數非同步程式設計:處理複雜任務的必備技巧 Nov 18, 2023 am 10:06 AM

JavaScript函數非同步程式設計:處理複雜任務的必備技巧引言:在現代前端開發中,處理複雜任務已經成為了必不可少的一部分。而JavaScript函數非同步程式設計技巧則是解決這些複雜任務的關鍵。本文將介紹JavaScript函數非同步程式設計的基本概念和常用的實作方法,並提供具體的程式碼範例,幫助讀者更好地理解和使用這些技巧。一、非同步程式設計的基本概念在傳統的同步程式設計中,程式碼按

如何在PHP中實現非同步訊息處理 如何在PHP中實現非同步訊息處理 Jul 10, 2023 am 08:19 AM

如何在PHP中實現非同步訊息處理引言:在現代的Web應用程式中,非同步訊息處理變得越來越重要。非同步訊息處理可以提高系統的效能和可擴展性,並改善使用者體驗。 PHP作為一種常用的伺服器端程式語言,也可以透過一些技術來實現非同步訊息處理。在本文中,我們將介紹一些PHP中實作非同步訊息處理的方法,並提供程式碼範例。使用訊息佇列訊息佇列是一種解耦系統元件的方式,它允許不同的元件在

Java框架非同步程式設計中常見的問題與解決方案 Java框架非同步程式設計中常見的問題與解決方案 Jun 04, 2024 pm 05:09 PM

Java框架非同步程式設計中常見的3個問題和解決方案:回呼地獄:使用Promise或CompletableFuture以更直覺的風格管理回呼。資源競爭:使用同步原語(如鎖)保護共享資源,並考慮使用執行緒安全性集合(如ConcurrentHashMap)。未處理異常:明確處理任務中的異常,並使用異常處理框架(如CompletableFuture.exceptionally())處理異常。

深入理解PHP8的新特性:如何有效地使用非同步程式設計和程式碼? 深入理解PHP8的新特性:如何有效地使用非同步程式設計和程式碼? Sep 11, 2023 pm 01:52 PM

深入理解PHP8的新特性:如何有效地使用非同步程式設計和程式碼? PHP8是PHP程式語言的最新主要版本,帶來了許多令人興奮的新功能和改進。其中最突出的特性之一是對非同步程式設計的支援。非同步程式設計可讓我們在處理並發任務時提高效能和回應能力。本文將深入探討PHP8的非同步程式設計特性,並介紹如何有效率地使用它們。首先,讓我們來了解一下什麼是非同步程式設計。在傳統的同步程式設計模型中,程式碼依照線性的順

golang框架如何處理並發和非同步程式設計? golang框架如何處理並發和非同步程式設計? Jun 02, 2024 pm 07:49 PM

Go框架利用Go的並發和非同步特性提供高效處理並發和非同步任務的機制:1.透過Goroutine實現並發,允許同時執行多個任務;2.透過通道實現非同步編程,在不阻塞主執行緒的情況下執行任務;3.適用於實戰場景,如並發處理HTTP請求、非同步取得資料庫資料等。

Python非同步程式設計: 實現高效並發的非同步程式碼之道 Python非同步程式設計: 實現高效並發的非同步程式碼之道 Feb 26, 2024 am 10:00 AM

1.為什麼要使用非同步程式設計?傳統程式設計使用阻塞式I/O,這表示程式會等待某個操作完成,然後才能繼續執行。這對於處理單一任務可能很有效,但對於處理大量任務時,可能會導致程式變慢。非同步程式設計則打破了傳統阻塞式I/O的限制,它使用非阻塞式I/O,這意味著程式可以將任務分發到不同的執行緒或事件循環中執行,而無需等待任務完成。這允許程式同時處理多個任務,提高程式的效能和效率。 2.python非同步程式設計的基礎Python非同步程式設計的基礎是協程和事件循環。協程是允許函數在暫停和恢復之間切換的函數。事件循環則負責調度

See all articles