摘要:題外今天嘗試了一下從文件經(jīng)過再到文件的整個過程,這也是這種靜態(tài)博客生成過程中的一環(huán)。這過程中,用到的中的系統(tǒng),寫的過程中恰好也經(jīng)歷了從到再到的轉(zhuǎn)變。可以看到上面的函數(shù)已經(jīng)非常順序化了,當(dāng)有個異步函數(shù)回調(diào)時,只需要順序?qū)懢涂梢岳病?/p>
題外:今天嘗試了一下從Markdown文件經(jīng)過ejs再到html文件的整個過程,這也是Hexo這種靜態(tài)博客生成過程中的一環(huán)。這過程中,用到的Node中的fs系統(tǒng),寫的過程中恰好也經(jīng)歷了從Callback到Promise再到Async的轉(zhuǎn)變。文末有福利哦!
在Node開發(fā)過程中,經(jīng)常會遇到異步的情況,異步簡單的說就是一個函數(shù)在返回時,調(diào)用者不能得到最終結(jié)果,而是需要等待一段時間才能得到,那么這個函數(shù)可以算作異步函數(shù)。那在Node開發(fā)中具體可以體現(xiàn)為資源的請求,例如訪問數(shù)據(jù)庫、讀寫文件等等。下面舉個小例子來代碼演示一下。
Callback先上代碼:
const fs = require("fs"), ejs = require("ejs"), matter = require("gray-matter"), showdown = require("showdown"), converter = new showdown.Converter() fs.readFile("./source/hello.md", "utf8", (error, data) => { if (error) { console.log(error) return } else { const mdData = matter(data) const html = converter.makeHtml(mdData.content) fs.readFile("./views/index.ejs", "utf8", (error, data) => { if (error) { console.log(error) return } else { // ejs to html const template = ejs.compile(data) const htmlStr = template({content: html}) fs.writeFile("./public/index.html", htmlStr, (error) => { if (error) { console.log(error) return } else { console.log("success") } }) } }) } })
可以看到,這只是寫了三個讀寫文件,嵌套就顯得非常臃腫,可以預(yù)見到當(dāng)有更多的callback將是怎樣一個情景,代碼做了什么東西就不解釋了,主要看一下callback的場景,在讀或?qū)懳募罂梢愿粋€回調(diào)函數(shù),當(dāng)前一個讀文件操作完成之后,才能在回調(diào)中利用結(jié)果來執(zhí)行下一個讀文件和寫文件,通過回調(diào)來保證函數(shù)的執(zhí)行順序。具體fs的使用,可見Node-fs文檔
Promise來看看引入Promise之后的寫法:
const readFileAsync = function (path) { return new Promise((resolve, reject) => { fs.readFile(path, "utf8", (error, data) => { if (error) { reject(error) } else { resolve(data) } }) }) } const writeFileAsync = function (path, data) { return new Promise((resolve, reject) => { fs.writeFile(path, data, (error, data) => { if (error) { reject(error) } else { resolve(data) } }) }) } let html = "" readFileAsync("./source/hello.md") .then((data1) => { const mdData = matter(data1) html = converter.makeHtml(mdData.content) return readFileAsync("./views/index.ejs") }) .then((data2) => { const template = ejs.compile(data2) const htmlStr = template({content: html}) return writeFileAsync("./public/index2.html", htmlStr) }) .then(() => console.log("success")) .catch(error => console.log(error))
這里只是簡單的用Promise封裝了一下fs的兩個函數(shù),拿其中一個函數(shù)來說,readFileAsync返回了一個Promise對象,這樣就可以通過這個對象來使用then進行結(jié)果回調(diào),雖然在封裝的時候需要寫一些代碼,但是當(dāng)有多處使用的時候,代碼可以明顯的簡潔許多,不同再一層一層地向右縮進。另外有一些工具庫如bluebird提供了API,可以很方便地處理異步。
在下面的代碼中使用bluebird
Async await還是先上代碼:
const fs = require("fs"), ejs = require("ejs"), matter = require("gray-matter"), showdown = require("showdown"), converter = new showdown.Converter(), Promise = require("bluebird") Promise.promisifyAll(fs) async function renderHtml() { const data1 = await fs.readFileAsync("./source/hello.md", "utf8") const mdData = matter(data1) const html = converter.makeHtml(mdData.content) const data2 = await fs.readFileAsync("./views/index.ejs", "utf8") const template = ejs.compile(data2) const htmlStr = template({content: html}) fs.writeFile("./public/index4.html", htmlStr) console.log("success") } renderHtml()
在Node7.6以上就已經(jīng)支持async function了,定義時只需要在function之前添加async關(guān)鍵字,而await也只能在async function中使用,一般會跟一個Promise對象,表示等待Promise返回結(jié)果后,再繼續(xù)執(zhí)行。
可以看到上面的函數(shù)已經(jīng)非常順序化了,當(dāng)有n個異步函數(shù)回調(diào)時,只需要順序?qū)懢涂梢岳病?梢钥闯?,其?b>async await也離不開Promise,只不過寫法上消除了then中帶有callback的那一絲絲影子,讓代碼更加優(yōu)雅~,因為沒有了then,可以用try catch進行錯誤處理
VSCode插件推薦小彩蛋來啦,正好結(jié)合這個例子,為方便實時看到每一步的執(zhí)行結(jié)果,推薦一個VSCode
插件:Quokka.ja
可以實時地進行代碼的執(zhí)行結(jié)果,再也不用console.log之后去看終端了。當(dāng)然,在實際開發(fā)中可能應(yīng)用性不是特別強,尤其是對于上下文強依賴型、后端請求依賴型的場景。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/84971.html
摘要:簽訂協(xié)議的兩方分別是異步接口和。在異步函數(shù)中,使用異常捕獲的方案,代替了的異常捕獲的方案。需要注意的是,在異步函數(shù)中使異步函數(shù)用時要使用,不然異步函會被同步執(zhí)行。 同步與異步 通常,代碼是由上往下依次執(zhí)行的。如果有多個任務(wù),就必需排隊,前一個任務(wù)完成,后一個任務(wù)才會執(zhí)行。這種執(zhí)行模式稱之為: 同步(synchronous) 。新手容易把計算機用語中的同步,和日常用語中的同步弄混淆。如,...
摘要:作者珂珂滬江前端開發(fā)工程師本文為原創(chuàng)文章,有不當(dāng)之處歡迎指出。只對未來發(fā)生的事情做出兩種基本情況的應(yīng)對成功和失敗。在異步轉(zhuǎn)同步這條道路上,只是一個出彩的點,他還尚有一些缺陷和不足,并不是我們最終的解決方案。 作者:珂珂 (滬江前端開發(fā)工程師)本文為原創(chuàng)文章,有不當(dāng)之處歡迎指出。轉(zhuǎn)載請標(biāo)明出處。 一個新事物的產(chǎn)生必然是有其歷史原因的。為了更好的以同步的方式寫異步的代碼,人們在JS上操碎了...
摘要:但是的的出現(xiàn)碉堡的新朋友,我們可以輕松寫出同步風(fēng)格的代碼同時又擁有異步機制,可以說是目前最簡單,最優(yōu)雅,最佳的解決方案了。不敢說這一定是終極的解決方案,但確實是目前最優(yōu)雅的解決方案 一、異步解決方案的進化史 JavaScript的異步操作一直是個麻煩事,所以不斷有人提出它的各種解決方案??梢宰匪莸阶钤绲幕卣{(diào)函數(shù)(ajax老朋友),到Promise(不算新的朋友),再到ES6的Gener...
閱讀 3889·2023-04-26 00:36
閱讀 2685·2021-11-16 11:44
閱讀 1109·2021-11-15 17:58
閱讀 1682·2021-09-30 09:47
閱讀 1225·2019-08-30 13:05
閱讀 1557·2019-08-30 12:55
閱讀 2424·2019-08-30 11:02
閱讀 2756·2019-08-29 17:01