當前位置: 首頁 / 技術分享 / 正文
Promise、generato....sync類同步編程

2022-11-25

   res ajax

  受javascript語言特性的影響,編程過程中充斥著大量異步回調,這會讓代碼維護起來特別麻煩,一步步走向回調地獄。社區中最早提出Promise解決方案,es6將其融入語法標準,并提供了generator、async,向類同步編程不斷努力。本文會通過這三個方面演示類同步進化過程。 ##1.Promise Promise提供異步編程的容器,包含異步代碼,在得到異步結果時,通過resolve傳遞數據(resove對應then所指定的函數,其實也就是單個過程的異步回調,可以理解成將之前的回調函數放在then方法中定義)。 ######以ajax請求封裝為例:

  傳統形式

  function ajax(url, success) {

  var xhr = new XMLHttpRequest();

  xhr.open("GET", url);

  xhr.send();

  xhr.onreadystatechange = function () {

  if (xhr.status == 200 && xhr.readyState == 4) {

  //將請求結果作為實參傳入成功回調

  success(xhr.responseText);

  }

  }

  }

  //如果兩個異步過程有先后順序,則會出現這種嵌套情況

  ajax("http://vebcoder.cn:9527/api/getTypeOne", function (res) {

  console.log(res);

  ajax("http://vebcoder.cn:9527/api/goodList", function (res) {

  console.log(res);

  })

  })

  Promise形式

  function ajax(url) {

  //promise容器包裹異步過程

  return new Promise(resolve => {

  var xhr = new XMLHttpRequest();

  xhr.open("GET", url);

  xhr.send();

  xhr.onreadystatechange = function () {

  if (xhr.status == 200 && xhr.readyState == 4) {

  //將異步結果使用resolve進行傳遞

  resolve(xhr.responseText);

  }

  }

  })

  }

  ajax("http://vebcoder.cn:9527/api/getTypeOne")

  .then(res=>{

  console.log(JSON.parse(res))

  })

  .then(()=>{

  return ajax("http://vebcoder.cn:9527/api/goodList")

  })

  .then(res=>{

  console.log(JSON.parse(res))

  })

  解決了回調函數橫向發展的問題,變成了縱向發展結構。直觀確實很直觀但是一大堆的then方法,!接下來generator登場

  2.generator

  乍一看,generator不過是一個有多個返回值的函數而已,奧妙在于如果不調用next方法,代碼會停止執行的。

  基礎用法

  //function后加*

  function* Gen(){

  console.log(1);

  yield;

  console.log(2)

  yield;

  console.log(3);

  return;

  }

  //調用函數獲得指針對象

  var g=Gen();

  g.next();//1

  g.next();//2

  g.next();//3

  第一次調用next執行到第一個yield,第三次執行到函數末尾return的位置。

  奧妙之處

  function* Gen(){

  //用變量接收yield命令

  var res=yield;

  console.log(res)

  }

  var g=Gen();

  g.next();

  //next傳入參數

  g.next(100);//100

  第一次調用next方法,代碼執行到yield停止執行。第二次調用next傳入參數,代碼繼續執行,并將傳入next的參數賦值給res變量。next方法可以帶一個參數,該參數就會被當作上一個yield表達式的返回值。 那么我們就可以這樣做:

  //上述封裝的ajax方法-傳統形式

  function* Gen(){

  //請求成功開始下一步

  ajax("http://vebcoder.cn:9527/api/getTypeOne",res=>{g.next(res)})

  // 接收yield返回值

  let res=yield;

  console.log(res)//請求的數據結果

  }

  var g=Gen();

  // 開始執行代碼

  g.next();

  //上述封裝的ajax方法-Promise形式

  function* Gen(){

  //請求成功開始下一步

  ajax("http://vebcoder.cn:9527/api/getTypeOne").then(res=>{g.next(res)})

  // 接收yield返回值

  let res=yield;

  console.log(res)//請求的數據結果

  }

  var g=Gen();

  // 開始執行代碼

  g.next();

  使用口訣:上一步回調,下一步,接收yield等待結果傳入

  按理說這種形式已經不錯了,不用再往下看了,除非你能忍住!

  3.async

  async是generator的語法糖,你只需關注兩部、步操作就行。相當于對Promise和generator進行了融合。

  async function Asy(){

  //等待promise實例

  let res=await ajax("http://vebcoder.cn:9527/api/getTypeOne")

  console.log(res)//請求的數據結果

  }

  Asy();

  //結合自執行函數

  ;(async function(){

  let res=await ajax("http://vebcoder.cn:9527/api/getTypeOne")

  console.log(res)//請求的數據結果

  }())

  async函數就是將Generator 函數的星號(*)替換成async,將yield替換成await。 注意:await后面需要跟一個promise實例,無需手動傳遞結果!

  最后來一個對比(有次序的異步過程):

  //傳統方式(對應上述傳統ajax封裝形式)

  ajax("http://vebcoder.cn:9527/api/getTypeOne", function (res) {

  console.log(res);

  ajax("http://vebcoder.cn:9527/api/goodList", function (res) {

  console.log(res);

  })

  })

  //promise (對應上述promise ajax封裝形式)

  ajax("http://vebcoder.cn:9527/api/getTypeOne")

  .then(res=>{

  console.log(JSON.parse(res))

  })

  .then(()=>{

  return ajax("http://vebcoder.cn:9527/api/goodList")

  })

  .then(res=>{

  console.log(JSON.parse(res))

  })

  //generator (對應上述promise ajax封裝形式)

  function* Gen(){

  //請求成功開始下一步

  ajax("http://vebcoder.cn:9527/api/getTypeOne").then(res=>{g.next(res)})

  // 接收yield返回值

  let res=yield;

  console.log(res);

  ajax("http://vebcoder.cn:9527/api/goodList").then(res=>{g.next(res)})

  // 接收yield返回值

  let res2=yield;

  console.log(res2);

  }

  var g=Gen();

  // 開始執行代碼

  g.next();

  //async (對應上述promise ajax封裝形式)

  // 發送請求

  ;(async function(){

  let res=await ajax("http://vebcoder.cn:9527/api/getTypeOne")

  console.log(res)//請求的數據結果

  let res2=await ajax("http://vebcoder.cn:9527/api/goodList")

  console.log(res2)//請求的數據結果

  }())

  async有更好的語義,幾乎達到與同步代碼一樣的編程體驗!

好程序員公眾號

  • · 剖析行業發展趨勢
  • · 匯聚企業項目源碼

好程序員開班動態

More+
  • HTML5大前端 <高端班>

    開班時間:2021-04-12(深圳)

    開班盛況

    開班時間:2021-05-17(北京)

    開班盛況
  • 大數據+人工智能 <高端班>

    開班時間:2021-03-22(杭州)

    開班盛況

    開班時間:2021-04-26(北京)

    開班盛況
  • JavaEE分布式開發 <高端班>

    開班時間:2021-05-10(北京)

    開班盛況

    開班時間:2021-02-22(北京)

    開班盛況
  • Python人工智能+數據分析 <高端班>

    開班時間:2021-07-12(北京)

    預約報名

    開班時間:2020-09-21(上海)

    開班盛況
  • 云計算開發 <高端班>

    開班時間:2021-07-12(北京)

    預約報名

    開班時間:2019-07-22(北京)

    開班盛況
在線咨詢
試聽
入學教程
立即報名

Copyright 2011-2023 北京千鋒互聯科技有限公司 .All Right 京ICP備12003911號-5 京公網安備 11010802035720號

美女裸体黄网站18禁免费_美女裸体黄网站啪啪18禁_美女裸体黄污18禁网站免费下载