成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

【Node Hero】3. 理解異步編程

kevin / 999人閱讀

摘要:異步編程在傳統(tǒng)編程實(shí)踐中,大多數(shù)操作都是同步發(fā)生的。中的異步編程異步是一種輸入輸出處理的形式,它允許在傳輸完成之前,其它處理能繼續(xù)進(jìn)行。

本文轉(zhuǎn)載自:眾成翻譯
譯者:網(wǎng)絡(luò)埋伏紀(jì)事
鏈接:http://www.zcfy.cc/article/1759
原文:https://blog.risingstack.com/node-hero-async-programming-in-node-js/

本章我將指導(dǎo)你學(xué)習(xí)異步編程的原理,并向你展示如何在 JavaScript 和 Node.js 中實(shí)現(xiàn)異步編程。

異步編程

在傳統(tǒng)編程實(shí)踐中,大多數(shù) I/O 操作都是同步發(fā)生的。如果想想 Java,想想如何用 Java 讀取一個文件,你會得到下面這樣的代碼:

try(FileInputStream inputStream = new FileInputStream("foo.txt")) {  
    Session IOUtils;
    String fileContent = IOUtils.toString(inputStream);
}

這背后發(fā)生了什么?主線程會被阻塞,直到文件讀完,這意味著讀文件的同時其它什么事情都做不了。要解決此問題,更好利用 CPU,就不得不手動管理線程。

如果有更多阻塞操作,那么事件隊(duì)列就變得更糟糕:

(紅色塊表示在進(jìn)程等待外部資源的響應(yīng)而被阻塞時,黑色塊表示在代碼運(yùn)行時,綠色塊表示應(yīng)用的其余部分)

為解決這個問題,Node.js 引入了一種異步編程模型。

Node.js 中的異步編程

異步 I/O 是一種輸入/輸出處理的形式,它允許在傳輸完成之前,其它處理能繼續(xù)進(jìn)行。

在如下的示例中,我將展示 Node.js 中一個簡單的文件讀寫過程 - 同時采用同步和異步的方式,目的是向你展示通過避免阻塞應(yīng)用程序,能實(shí)現(xiàn)什么。

下面我們先從一個簡單的示例開始 - 以同步的方式用 Node.js 讀一個文件:

const fs = require("fs")  
let content  
try {  
  content = fs.readFileSync("file.md", "utf-8")
} catch (ex) {
  console.log(ex)
}
console.log(content)  

這里剛剛發(fā)生了什么?我們試圖用 fs 模塊的同步接口讀一個文件。它按預(yù)期方式工作 - content 變量會包含 file.md 的內(nèi)容。這種方式的問題是,Node.js 會被阻塞,直到操作完成 - 也就是說在文件正在被讀取時,它什么事都做不了。

下面我們看看如何修復(fù)!

我們直到,在 JavaScript 中,異步編程只能用函數(shù)這個該語言的一等公民來實(shí)現(xiàn):函數(shù)可以像所有其它變量一樣傳給其它函數(shù)。將其它函數(shù)作為參數(shù)的函數(shù)被稱為高階函數(shù)。

如下是一個高階函數(shù)的最簡單示例:

const numbers = [2,4,1,5,4]

function isBiggerThanTwo (num) {  
  return num > 2
}

numbers.filter(isBiggerThanTwo)  

在上例中,我們將一個函數(shù)傳遞給 filter 函數(shù)。通過這種方式我們可以定義過濾的邏輯。

這就是回調(diào)誕生的方式:如果你把一個函數(shù)傳遞給另一個函數(shù)作為參數(shù),那么就可以在另一個函數(shù)完成任務(wù)時,在該函數(shù)內(nèi)調(diào)用傳進(jìn)來的函數(shù)。不需要返回值,只用值調(diào)用另一個函數(shù)。

這些所謂錯誤優(yōu)先(error-first)的回調(diào)是 Node.js 本身的核心 - 核心模塊用了它,大多數(shù) NPM 中的模塊也是。

const fs = require("fs")  
fs.readFile("file.md", "utf-8", function (err, content) {  
  if (err) {
    return console.log(err)
  }

  console.log(content)
})

這里要注意:

錯誤處理: 必須在回調(diào)中檢測錯誤,而不是用 try-catch 塊。

沒有返回值: 異步函數(shù)不返回值,但是值將被傳遞給回調(diào)。

下面我們對這個文件做點(diǎn)修改,看看它實(shí)際上是如何工作的:

const fs = require("fs")

console.log("start reading a file...")

fs.readFile("file.md", "utf-8", function (err, content) {  
  if (err) {
    console.log("error happened during reading the file")
    return console.log(err)
  }

  console.log(content)
})

console.log("end of the file")  

這段腳本的輸出將是:

start reading a file...  
end of the file  
error happened during reading the file  

正如你所見,一旦我們開始讀文件,執(zhí)行繼續(xù),應(yīng)用程序打印出 end of the file。一旦文件讀取完成,我們的回調(diào)就只被調(diào)用一次。這怎么可能呢?迎接事件循環(huán)。

事件循環(huán)

事件循環(huán)是 Node.js / JavaScript 的核心 - 它負(fù)責(zé)安排異步操作。

在深入了解之前,要確保理解什么是事件驅(qū)動的編程。

事件驅(qū)動的編程是一種編程范式,在這種范式中程序流程是由事件決定的,比如用戶行為(鼠標(biāo)點(diǎn)擊、按鍵)、傳感器輸出或者其它程序/線程的消息。

實(shí)際上,它意味著應(yīng)用程序按照事件行事。

并且,我們在第一章已經(jīng)學(xué)過,從開發(fā)者的觀點(diǎn)看,Node.js 是單線程的。這意味著不必處理線程和線程同步,Node.js 遠(yuǎn)離了這種復(fù)雜性。除了你的代碼,所有東西都是并行執(zhí)行的。

要更深入理解事件循環(huán),請繼續(xù) youtube 上的視頻。

異步控制流

至此你已經(jīng)對 JavaScript 中的異步編程工作機(jī)制有了一個基本認(rèn)識,下面我們來看看幾個如何組織代碼的示例。

Async.js

為避免所謂回調(diào)地獄,可以做的一件事情是開始使用 async.js。

Async.js 幫助組織應(yīng)用程序結(jié)構(gòu),讓流程控制更容易。

下面我們看一個使用 Async.js 的簡短示例,然后用 Promises 重寫。

如下的代碼片段映射三個文件上的狀態(tài):

async.parallel(["file1", "file2", "file3"], fs.stat, function (err, results) {  
    // 現(xiàn)在結(jié)果是是一個每個文件的狀態(tài)數(shù)組
})
Promises

Promise 對象用于延遲及異步計(jì)算。一個 Promise 代表還沒有完成,但是未來會執(zhí)行的操作。

在實(shí)踐中,前面的示例可以重寫為如下:

function stats (file) {  
  return new Promise((resolve, reject) => {
    fs.stat(file, (err, data) => {
      if (err) {
        return reject (err)
      }
      resolve(data)
    })
  })
}

Promise.all([  
  stats("file1"),
  stats("file2"),
  stats("file3")
])
.then((data) => console.log(data))
.catch((err) => console.log(err))

當(dāng)然,如果使用一個有 Promise 接口的方法,那么 Promise 示例的行數(shù)也會少很多。

下一步:第一個 Node.js 服務(wù)器

下一章將會學(xué)習(xí)如何啟動第一個 Node.js HTTP 服務(wù)器。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/84981.html

相關(guān)文章

  • Node Hero】1. 開始使用 Node.js

    摘要:使用一個事件驅(qū)動的非阻塞式的模型,讓它輕量而高效。也就是說提供了用編寫服務(wù)器的可能性,這種服務(wù)器具有令人難以置信的性能。正如官方聲明所說是一個使用與瀏覽器相同引擎的運(yùn)行時。這意味著有兩個發(fā)布版本穩(wěn)定版和試驗(yàn)版。 本文轉(zhuǎn)載自:眾成翻譯譯者:網(wǎng)絡(luò)埋伏紀(jì)事鏈接:http://www.zcfy.cc/article/1748原文:https://blog.risingstack.com/nod...

    hqman 評論0 收藏0
  • Node Hero】2. 使用 NPM

    摘要:網(wǎng)站和使用同樣的注冊庫來顯示模塊以及查找模塊。使用在上一章開始使用中,當(dāng)創(chuàng)建文件時,已經(jīng)遇到了。此外,全局命名空間只包含公共模塊。通過引入作用域包來解決此問題。下一步異步編程下一章學(xué)習(xí)使用回調(diào)和實(shí)現(xiàn)異步編程的原理。 本文轉(zhuǎn)載自:眾成翻譯譯者:網(wǎng)絡(luò)埋伏紀(jì)事鏈接:http://www.zcfy.cc/article/1749原文:https://blog.risingstack.com/n...

    CarterLi 評論0 收藏0
  • 【響應(yīng)式編程的思維藝術(shù)】 (5)Angular中Rxjs的應(yīng)用示例

    摘要:本文是響應(yīng)式編程第四章構(gòu)建完整的應(yīng)用程序這篇文章的學(xué)習(xí)筆記。涉及的運(yùn)算符每隔指定時間將流中的數(shù)據(jù)以數(shù)組形式推送出去。中提供了一種叫做異步管道的模板語法,可以直接在的微語法中使用可觀測對象示例五一點(diǎn)建議一定要好好讀官方文檔。 本文是【Rxjs 響應(yīng)式編程-第四章 構(gòu)建完整的Web應(yīng)用程序】這篇文章的學(xué)習(xí)筆記。示例代碼托管在:http://www.github.com/dashnoword...

    shenhualong 評論0 收藏0
  • Node Hero】7. Node.js 項(xiàng)目結(jié)構(gòu)

    摘要:本教程會學(xué)習(xí)如何正確組織一個項(xiàng)目的結(jié)構(gòu),從而在應(yīng)用程序開始增長時避免混亂。項(xiàng)目結(jié)構(gòu)的五個基本規(guī)則組織項(xiàng)目有不少可能的方式并且每種已知的方式都有其興衰。過去在,我們有機(jī)會創(chuàng)建各種規(guī)模的高效應(yīng)用程序,也獲得了大量關(guān)于項(xiàng)目結(jié)構(gòu)注意事項(xiàng)的見解。 本文轉(zhuǎn)載自:眾成翻譯譯者:網(wǎng)絡(luò)埋伏紀(jì)事鏈接:http://www.zcfy.cc/article/1756原文:https://blog.rising...

    張紅新 評論0 收藏0
  • JavaScript設(shè)計(jì)模式

    摘要:可能因?yàn)橄热霝橹鳎诰幊讨?,往往不由自主地以的邏輯編程思路設(shè)計(jì)模式進(jìn)行開發(fā)。這是原型模式很重要的一條原則。關(guān)于閉包與內(nèi)存泄露的問題,請移步原型模式閉包與高階函數(shù)應(yīng)該可以說是設(shè)計(jì)模式的基礎(chǔ)要領(lǐng)吧。在下一章,再分享一下的幾種常用設(shè)計(jì)模式。 前 在學(xué)習(xí)使用Javascript之前,我的程序猿生涯里面僅有接觸的編程語言是C#跟Java——忽略當(dāng)年在大學(xué)補(bǔ)考了N次的C與VB。 從靜態(tài)編程語言,...

    keke 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<