如何在Javascript中使用async awai方法?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
目前累計服務(wù)客戶上1000家,積累了豐富的產(chǎn)品開發(fā)及服務(wù)經(jīng)驗。以網(wǎng)站設(shè)計水平和技術(shù)實力,樹立企業(yè)形象,為客戶提供網(wǎng)站設(shè)計制作、成都做網(wǎng)站、網(wǎng)站策劃、網(wǎng)頁設(shè)計、網(wǎng)絡(luò)營銷、VI設(shè)計、網(wǎng)站改版、漏洞修補等服務(wù)。創(chuàng)新互聯(lián)公司始終以務(wù)實、誠信為根本,不斷創(chuàng)新和提高建站品質(zhì),通過對領(lǐng)先技術(shù)的掌握、對創(chuàng)意設(shè)計的研究、對客戶形象的視覺傳遞、對應(yīng)用系統(tǒng)的結(jié)合,為客戶提供更好的一站式互聯(lián)網(wǎng)解決方案,攜手廣大客戶,共同發(fā)展進步。Promise對異步的處理
雖然Node.js的異步IO帶來了對高并發(fā)的良好支持,同時也讓“回調(diào)”成為災(zāi)難,很容易造成回調(diào)地獄。傳統(tǒng)的方式比如使用具名函數(shù),雖然可以減少嵌套的層數(shù),讓代碼看起來比較清晰。但是會造成比較差的編碼和調(diào)試體驗,你需要經(jīng)常使用用ctrl + f去尋找某個具名函數(shù)的定義,這使得IDE窗口經(jīng)常上下來回跳動。使用Promise之后,可以很好的減少嵌套的層數(shù)。另外Promise的實現(xiàn)采用了狀態(tài)機,在函數(shù)里面可以很好的通過resolve和reject進行流程控制,你可以按照順序鏈式的去執(zhí)行一系列代碼邏輯了。下面是使用Promise的一個例子:
const request = require('request'); // 請求的url和header const options = { url: 'https://api.github.com/repos/cpselvis/zhihu-crawler', headers: { 'User-Agent': 'request' } }; // 獲取倉庫信息 const getRepoData = () => { return new Promise((resolve, reject) => { request(options, (err, res, body) => { if (err) { reject(err); } resolve(body); }); }); }; getRepoData() .then((result) => console.log(result);) .catch((reason) => console.error(reason);); // 此處如果是多個Promise順序執(zhí)行的話,如下: // 每個then里面去執(zhí)行下一個promise // getRepoData() // .then((value2) => {return promise2}) // .then((value3) => {return promise3}) // .then((x) => console.log(x))
不過Promise仍然存在缺陷,它只是減少了嵌套,并不能完全消除嵌套。舉個例子,對于多個promise串行執(zhí)行的情況,第一個promise的邏輯執(zhí)行完之后,我們需要在它的then函數(shù)里面去執(zhí)行第二個promise,這個時候會產(chǎn)生一層嵌套。另外,采用Promise的代碼看起來依然是異步的,如果寫的代碼如果能夠變成同步該多好啊!
Generator對異步的處理
談到generator,你應(yīng)該不會對它感到陌生。在Node.js中對于回調(diào)的處理,我們經(jīng)常用的TJ / Co就是使用generator結(jié)合promise來實現(xiàn)的,co是coroutine的簡稱,借鑒于python、lua等語言中的協(xié)程。它可以將異步的代碼邏輯寫成同步的方式,這使得代碼的閱讀和組織變得更加清晰,也便于調(diào)試。
const co = require('co'); const request = require('request'); const options = { url: 'https://api.github.com/repos/cpselvis/zhihu-crawler', headers: { 'User-Agent': 'request' } }; // yield后面是一個生成器 generator const getRepoData = function* () { return new Promise((resolve, reject) => { request(options, (err, res, body) => { if (err) { reject(err); } resolve(body); }); }); }; co(function* () { const result = yield getRepoData; // ... 如果有多個異步流程,可以放在這里,比如 // const r1 = yield getR1; // const r2 = yield getR2; // const r3 = yield getR3; // 每個yield相當于暫停,執(zhí)行yield之后會等待它后面的generator返回值之后再執(zhí)行后面其它的yield邏輯。 return result; }).then(function (value) { console.log(value); }, function (err) { console.error(err.stack); });
async / await對異步的處理
雖然co是社區(qū)里面的優(yōu)秀異步解決方案,但是并不是語言標準,只是一個過渡方案。ES7語言層面提供async / await去解決語言層面的難題。目前async / await 在 IE edge中已經(jīng)可以直接使用了,但是chrome和Node.js還沒有支持。幸運的是,babel已經(jīng)支持async的transform了,所以我們使用的時候引入babel就行。在開始之前我們需要引入以下的package,preset-stage-3里就有我們需要的async/await的編譯文件。
無論是在Browser還是Node.js端都需要安裝下面的包。
$ npm install babel-core --save $ npm install babel-preset-es2015 --save $ npm install babel-preset-stage-3 --save
這里推薦使用babel官方提供的require hook方法。就是通過require進來后,接下來的文件進行require的時候都會經(jīng)過Babel的處理。因為我們知道CommonJs是同步的模塊依賴,所以也是可行的方法。這個時候,需要編寫兩個文件,一個是啟動的js文件,另外一個是真正執(zhí)行程序的js文件。
啟動文件index.js
require('babel-core/register'); require('./async.js');
真正執(zhí)行程序的async.js
const request = require('request'); const options = { url: 'https://api.github.com/repos/cpselvis/zhihu-crawler', headers: { 'User-Agent': 'request' } }; const getRepoData = () => { return new Promise((resolve, reject) => { request(options, (err, res, body) => { if (err) { reject(err); } resolve(body); }); }); }; async function asyncFun() { try { const value = await getRepoData(); // ... 和上面的yield類似,如果有多個異步流程,可以放在這里,比如 // const r1 = await getR1(); // const r2 = await getR2(); // const r3 = await getR3(); // 每個await相當于暫停,執(zhí)行await之后會等待它后面的函數(shù)(不是generator)返回值之后再執(zhí)行后面其它的await邏輯。 return value; } catch (err) { console.log(err); } } asyncFun().then(x => console.log(`x: ${x}`)).catch(err => console.error(err));
注意點:
async用來申明里面包裹的內(nèi)容可以進行同步的方式執(zhí)行,await則是進行執(zhí)行順序控制,每次執(zhí)行一個await,程序都會暫停等待await返回值,然后再執(zhí)行之后的await。
await后面調(diào)用的函數(shù)需要返回一個promise,另外這個函數(shù)是一個普通的函數(shù)即可,而不是generator。
await只能用在async函數(shù)之中,用在普通函數(shù)中會報錯。
await命令后面的 Promise 對象,運行結(jié)果可能是 rejected,所以最好把 await 命令放在 try...catch 代碼塊中。
其實,async / await的用法和co差不多,await和yield都是表示暫停,外面包裹一層async 或者 co來表示里面的代碼可以采用同步的方式進行處理。不過async / await里面的await后面跟著的函數(shù)不需要額外處理,co是需要將它寫成一個generator的。
看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)建站的支持。
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站m.rwnh.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、建站服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。
當前名稱:如何在Javascript中使用asyncawai方法-創(chuàng)新互聯(lián)
URL地址:http://m.rwnh.cn/article26/djiicg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供服務(wù)器托管、軟件開發(fā)、品牌網(wǎng)站設(shè)計、微信公眾號、小程序開發(fā)、App設(shè)計
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容