真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Javascript中async/await是怎樣工作的-創(chuàng)新互聯(lián)

這篇文章主要介紹了Javascript中async/await是怎樣工作的,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

目前創(chuàng)新互聯(lián)建站已為上1000+的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)頁空間、綿陽服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計、細河網(wǎng)站維護等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

async / await是ES7的重要特性之一,也是目前社區(qū)里公認的優(yōu)秀異步解決方案。目前,async / await這個特性已經(jīng)是stage 3的建議,可以看看TC39的進度,本篇文章將分享async / await是如何工作的,閱讀本文前,希望你具備Promise、generator、yield等ES6的相關(guān)知識。

在詳細介紹async / await之前,先回顧下目前在ES6中比較好的異步處理辦法。下面的例子中數(shù)據(jù)請求用Node.js中的request模塊,數(shù)據(jù)接口采用Github v3 api文檔提供的repo代碼倉庫詳情API作為例子演示。

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的。

感謝你能夠認真閱讀完這篇文章,希望小編分享的“Javascript中async/await是怎樣工作的”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián)網(wǎng)站建設(shè)公司,,關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識等著你來學(xué)習(xí)!


當前題目:Javascript中async/await是怎樣工作的-創(chuàng)新互聯(lián)
文章來源:http://weahome.cn/article/cscghe.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部