亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

NodeJs通過async/await處理異步的方法

 更新時間:2017年10月09日 11:49:05   作者:Yika丶J  
本篇文章主要介紹了NodeJs通過async/await處理異步的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

場景

遠古時代

我們在編寫express后臺,經(jīng)常要有許多異步IO的處理。在遠古時代,我們都是用chunk函數(shù)處理,也就是我們最熟悉的那種默認第一個參數(shù)是error的函數(shù)。我們來模擬一個Mongo數(shù)據(jù)庫的操作,感受一下。

mongoDb.open(function(err, db){
  if(!err){
    db.collection("users", function(err, collection){
      if(!err){
        let person = {name: "yika", age: 20};
        collection.insert(person, function(err, result){
          if(!err){
            console.log(result);
          }
        });
      }
    })
  }
});

這個也就是被我們所詬病的callback hell,一堆橫向金字塔,如果將回調(diào)拆分成函數(shù),則會變得非常支離破碎。為了防止到惡心到大家,我甚至沒有寫關(guān)于錯誤的處理,正常來說,每一個異步的操作都需要都它的error進行相應(yīng)的顯示或處理的。

Promise時代

后來進入了好一點的時代就是Promise,我們也可以稱作鏈?zhǔn)讲僮?。關(guān)于Promise,我也是之前有專門寫過一系列的博文,有興趣可以回頭翻一下。這里來看看,將以上改寫之后的狀況。

let person = {name: "yika"};
mongoDb
  .open()
  .then(function(database){
   return database.collection("users");
  })
  .then(function(collection){
   return collection.insert(person);
  })
  .then(function(result){
   console.log(result);
  })
  .catch(function(e){
   throw new Error(e);
  })

我們可以看到,我們將金字塔已經(jīng)平鋪成一條線狀結(jié)構(gòu)了。相比之前惡心難以維護的chunk函數(shù),變成了promise函數(shù),并且錯誤的處理也變得十分優(yōu)雅。但是我們?nèi)匀徊豢珊鲆暷承﹩栴},例如我們必須忍受各個邏輯被一個又一個的then()包裹起來,每一個函數(shù)都有其獨立的作用域,如果為了共享某個數(shù)據(jù)就必須掛在最外層,最重要的還是,它與我們熟悉的同步編程仍然有差別。

Generator時代

TJ大神,借著ES6的Generator迭代器,最早實現(xiàn)了異步編程同步化的功能,也就是最為我們所熟知的co庫。我們通過co(function *(){})可以使函數(shù)內(nèi)部通過迭代器來控制。而co在這里則是充當(dāng)了啟動器的角色。關(guān)于Generator和co我在之前的博文也同樣說過。

let co = require("co");

co(function *(){
  let db, collection, result; 
  let person = {name: "yika"};
  try{
    db = yield mongoDb.open();
    collection = yield db.collection("users");
    result = yield collection.insert(person);
  }catch(e){
    console.error(e.message);
  }
  console.log(result);
});

我們已經(jīng)非常接近同步編程了,在co包裹的函數(shù)內(nèi)部,只有一個異步執(zhí)行完畢,才會繼續(xù)執(zhí)行下面的代碼。并且錯誤的處理也是通過try and catch進行實現(xiàn)的。不過我們不得不承認的是,迭代器終究不是為異步而存在的。里面的yield*的語義也并不代表的就是異步函數(shù)標(biāo)志。并且迭代器是需要co去驅(qū)動的,它和我們想象中的函數(shù)多少有一點點不同。

async/await時代

我們關(guān)注到ES7的async/await,才發(fā)現(xiàn)這才是我們想要的!我們將上面的代碼小小改寫一下。

async function insertData(person){
  let db, collection, result; 
  try{
    db = await mongoDb.open();
    collection = await db.collection("users");
    result = await collection.insert(person);
  }catch(e){
    console.error(e.message);
  }
  console.log(result);
} 

insertData({name: "yika"});

我們可以看到inserData是一個真正的函數(shù),是我們可以直接去調(diào)用而無需啟動器驅(qū)動的。當(dāng)然內(nèi)部我們也可以感受到處理yield變成了await以外,并沒有很大區(qū)別。async/await,更符合我們異步編程的語義。

那么問題來了,how to use it?

使用

我們一開始就說過,babel已經(jīng)支持async的transform了,所以我們使用的時候引入babel就行。當(dāng)然server端和browser端,可以有不同的處理方法。在開始之前我們需要引入以下的package,preset-stage-3里就有我們需要的async/await的編譯文件。

$ npm install babel-core --save
$ npm install babel-preset-es2015 --save
$ npm install babel-preset-stage-3 --save

Browser端

Babel一開始的出現(xiàn)就是為了讓舊瀏覽器也能支持新的ES6特性,提升我們的開發(fā)體驗。所以在Babel一開始就是可以通過babel-cli終端進行編譯的?;蛘咭隻abel文件在瀏覽器端進行編譯。當(dāng)然這些都不是我最推薦的,所以我就帶過不說啦。在前端靜態(tài)資源配置里,webpack是現(xiàn)在比較好的解決方案,它支持靜態(tài)資源的模塊依賴,打包合并,還有語言的預(yù)處理,當(dāng)然在這里我們就是指babel的處理。

// webpack.config.js
// 省略上面的文件輸入輸出的配置,直接看模塊加載器的配置
module: {
  loaders: [
    {
      test: /\.js$/,
      exclude: /(node_modules|bower_components)/,
      loader: "babel",
      query: {
       presets: ['es2015', 'stage-3']
      }
    },
  ]
}

這樣我們就可以愉快的使用了。

Server端

相對來說,后端比前端需要處理的異步IO地方多得多,也是更加需要這個。那我們在Server端又如何引入babel呢?

其實最簡單也是最麻煩的方法就是,直接把js文件通過babel編譯出新的文件再來使用。當(dāng)然也就免不了冗余文件了,眼不見心不煩,還是換一個方法吧。

我們使用官方提供的require hook方法,顧名思義就是通過require進來后,接下來的文件進行require的時候都會經(jīng)過Babel的處理。因為我們知道CommonJs是同步的模塊依賴,所以也是可行的方法。我們需要多一個用于啟動的js文件,一個真正執(zhí)行程序的js文件。

// index.js 
// 用于引入babel,并且啟動app.js

require("babel-core/register");
require("./app.js");

配置完hook之后,我們就配置babel的.babelrc文件,它是一個json格式的文件。es2015看情況配置,如果是已經(jīng)是Node5.0版本,就無需再進行編譯。

{
 "presets": ["stage-3", "es2015"]
}

最后我們的異步函數(shù)代碼,寫在app.js里即可。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • node.js中的http.request方法使用說明

    node.js中的http.request方法使用說明

    這篇文章主要介紹了node.js中的http.request方法使用說明,本文介紹了http.request的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼需要的朋友可以參考下
    2014-12-12
  • 利用nodejs讀取圖片并將二進制數(shù)據(jù)轉(zhuǎn)換成base64格式

    利用nodejs讀取圖片并將二進制數(shù)據(jù)轉(zhuǎn)換成base64格式

    這篇文章主要介紹了利用nodejs讀取圖片并將二進制數(shù)據(jù)轉(zhuǎn)換成base64格式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Koa2微信公眾號開發(fā)之本地開發(fā)調(diào)試環(huán)境搭建

    Koa2微信公眾號開發(fā)之本地開發(fā)調(diào)試環(huán)境搭建

    本篇文章主要介紹了Koa2微信公眾號開發(fā)之本地開發(fā)調(diào)試環(huán)境搭建,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • nodejs安裝與配置過程+初學(xué)實例解讀

    nodejs安裝與配置過程+初學(xué)實例解讀

    這篇文章主要介紹了nodejs安裝與配置過程+初學(xué)實例解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • jenkins配置不同版本nodeJS保姆級教程

    jenkins配置不同版本nodeJS保姆級教程

    Jenkins確實是個好工具,今天在配置vue項目的時侯,看著別人配置好的東西,可是我就明明在配置時,發(fā)現(xiàn)缺少node的版本選擇,這篇文章主要給大家介紹了關(guān)于jenkins配置不同版本nodeJS的相關(guān)資料,需要的朋友可以參考下
    2024-07-07
  • express如何使用session與cookie的方法

    express如何使用session與cookie的方法

    本篇文章主要介紹了express如何使用session與cookie的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • node靜態(tài)服務(wù)器實現(xiàn)靜態(tài)讀取文件或文件夾

    node靜態(tài)服務(wù)器實現(xiàn)靜態(tài)讀取文件或文件夾

    這篇文章主要介紹了node靜態(tài)服務(wù)器實現(xiàn)靜態(tài)讀取文件或文件夾,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • node.js中的fs.utimesSync方法使用說明

    node.js中的fs.utimesSync方法使用說明

    這篇文章主要介紹了node.js中的fs.utimesSync方法使用說明,本文介紹了fs.utimesSync的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • Yapi安裝部署詳細圖文教程

    Yapi安裝部署詳細圖文教程

    YApi 是一個可本地部署的、打通前后端及QA的、可視化的接口管理平臺,下面這篇文章主要給大家介紹了關(guān)于Yapi安裝部署的相關(guān)資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2022-09-09
  • 14款NodeJS Web框架推薦

    14款NodeJS Web框架推薦

    這篇文章主要介紹了14款NodeJS Web框架推薦,其中大多數(shù)框架都是基于node.js的Express實現(xiàn),需要的朋友可以參考下
    2014-07-07

最新評論