国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

js 異步編程

diabloneo / 454人閱讀

摘要:總結這篇文章簡單的介紹了一些常用的異步編程的方法,如果有錯誤或不嚴謹的地方,歡迎批評指正,如果喜歡,歡迎點贊收藏。

大家都知道js的執行環境是單線程的,如果沒有異步編程,那么js的執行效率會非常低下,導致程序十分卡頓,一提到異步編程大家首先的想到的一定是回調函數,這也是最常用的異步編程的形式,但其實常用的還有Promise和Async函數,接下來就讓我們一起學習這幾種常用的異步編程方法。

回調函數

回調函數就是把任務的第二段多帶帶寫在一個函數里面,等到重新執行這個任務的時候,就直接調用這個函數,來看一個簡單的例子:

function print(name, callback) {
  setTimeout(() => {
    console.log(name)
    if (callback) {
      callback()
    }
  }, 1000)
}
print("a", function () {
  print("b")
})

上面這個例子中將print("b")放在print("a")的回調函數中,這樣就能按順序依次打印a、b,但是回調函數有一個很明顯的問題,就是當回調函數嵌套過深時,會導致代碼混亂,不夠清晰,這就是人們常說的對調地獄,來看下面這個例子:

function print(name, callback) {
  setTimeout(() => {
    console.log(name)
    if (callback) {
      callback()
    }
  }, 1000)
}
print("a", function () {
  print("b", function () {
    print("c", function () {
      print("d")
    })
  })
})

當我們想按順序依次打印a、b、c、d時,代碼就變成上面的樣子,可以看到,我們的代碼形成四層嵌套,如果還要加回調函數就要繼續嵌套,這樣嵌套會越寫越深,越來越難以維護,此時我們就必須考慮用新的技術去改進,es6的Promise函數應運而生,接下來讓我們看Promise函數是如何改進這個問題的。

Promise
function print(name) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(name)
      resolve()
    }, 1000)
  })
}
print("a").then(() => {
  return print("b")
})
  .then(() => {
    return print("c")
  })
  .then(() => {
    return print("d")
  })

和之前用回調函數的形式相比,Promise函數寫法更加清晰,由回調函數的嵌套調用變成了鏈式調用,但是Promise也有一個很嚴重的問題就是代碼冗余,原來的任務被Promise包裝了一下,不管什么操作都是放在then函數里面,導致代碼的語以變差,有什么更好的解決辦法呢?如果您對Promise函數還想有更深入的了解,可以去看阮一峰老師es6入門

Async

在正式使用異步函數之前,先簡單的介紹一下它的用法,async通常與await一起使用,async函數返回一個Promise對象,可以使用then方法添加回調函數。當函數執行的時候,一旦遇到await就會先返回,等到觸發的異步操作完成,再接著執行函數體后面的語句。做了簡單的介紹后,接下來,我們來async函數是怎么對Promise調用優化的。看下面的例子:

function print(name) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(name)
      resolve()
    }, 1000)
  })
}
async function test () {
  await print("a")
  await print("b")
  await print("c")
  await print("d")
}
test()

async函數來處理之前的問題,代碼就是上面的這個例子中所展示的樣子,是不是感覺代碼瞬間清晰了,而且代碼更加好理解了,再仔細思考一下使用async異步函數就很完美了嗎?其實async異步函數也有其固有的問題,接下來我們就看看async異步函數還有什么問題需要解決。

錯誤捕獲

異步函數第一個需要解決的問題就是錯誤捕獲的問題,讓我們看看一般情況下async異步函數是怎么做錯誤捕獲的,來看一個例子:

function print(name) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(name)
      resolve()
    }, 1000)
  })
}
async function test () {
  try {
    await print("a")
  } catch (err) {
    console.log(err)
  }
}
test()

當使用上述形式的try,catch進行錯誤捕獲的時候,是不是覺得代碼和使用Promise函數時一樣啰嗦,那有沒有好的解決辦法呢?讓我們來看另外一個例子:

function print(name) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(name)
      resolve("a")
    }, 1000)
  })
}
async function test () {
  let [ err, result ] = await to(print("a"))
  if (err) throw err
  return result
}
test()

to.js:

function to(promise, errorExt) {
  return promise
    .then(function (data) { return [null, data]; })
    .catch(function (err) {
      if (errorExt) {
        Object.assign(err, errorExt);
      }
      return [err, undefined];
    });
}

export { to };
export default to;    

上述例子中,將async異步函數的錯誤處理封裝到了一個to.js中,這里面其實只有一個簡單方法,傳入一個Promise對象,對Promise對象進行錯誤捕獲返回值,用解構的形式獲取返回值和錯誤,這樣就不需要反復寫try catche做錯誤捕獲了。to.js是一個開源庫

異步陷阱

什么是異步陷阱呢?在使用async異步函數的時候,多個異步操作是可以同時執行,但是有await命令變成了繼發的形式了,即必須等待前一個執行完了后一個才能執行,還是之前的例子:

function print(name) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(name)
      resolve()
    }, 1000)
  })
}
async function test () {
  await print("a")
  await print("b")
  await print("c")
  await print("d")
}
test()

假設await print("a")、await print("b")、await print("c")、await print("d")這四個操作并沒有先后的邏輯關系,可以同時執行,那么按照上面的寫法就會導致前一個執行完再執行下一個,整個執行過程中的等待時間會有4s,但是同時執行的等待時間就只有1s,這是在使用async異步函數會經常忽略的一個問題,那么怎么解決呢?介紹一個我經常使用的辦法,看例子:

function print(name) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(name)
      resolve("a")
    }, 1000)
  })
}
async function test () {
  Promise.all([print("a"), print("b"), print("c"), print("d")])
}
test()

其實解決辦法很簡單就是通過Promise.all()方法,將所有異步操作作為參數數組傳入,這樣print("a")、print("b")、print("c")、print("d")這四個異步操作就可以并發執行了。

總結

這篇文章簡單的介紹了一些常用的異步編程的方法,如果有錯誤或不嚴謹的地方,歡迎批評指正,如果喜歡,歡迎點贊收藏。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/98835.html

相關文章

  • js學習之異步處理

    摘要:學習開發,無論是前端開發還是都避免不了要接觸異步編程這個問題就和其它大多數以多線程同步為主的編程語言不同的主要設計是單線程異步模型。由于異步編程可以實現非阻塞的調用效果,引入異步編程自然就是順理成章的事情了。 學習js開發,無論是前端開發還是node.js,都避免不了要接觸異步編程這個問題,就和其它大多數以多線程同步為主的編程語言不同,js的主要設計是單線程異步模型。正因為js天生的與...

    VioletJack 評論0 收藏0
  • 【Node Hero】3. 理解異步編程

    摘要:異步編程在傳統編程實踐中,大多數操作都是同步發生的。中的異步編程異步是一種輸入輸出處理的形式,它允許在傳輸完成之前,其它處理能繼續進行。 本文轉載自:眾成翻譯譯者:網絡埋伏紀事鏈接:http://www.zcfy.cc/article/1759原文:https://blog.risingstack.com/node-hero-async-programming-in-node-js/ ...

    kevin 評論0 收藏0
  • nodejs異步編程詳解

    摘要:四異步編程解決方案模式模式一定程度上緩解了嵌套回調的問題,只會處在未完成完成態失敗態中的一種,只會從未完成轉化為完成態或者失敗態,不能逆轉。 一、從一個簡單的案例開始 fs.readdir(path.join(__dirname, ./index.js), (err, files) => { files.foreach((filename, index) => { ...

    inapt 評論0 收藏0
  • JavaScript 異步編程

    摘要:下面我將介紹的基本用法以及如何在異步編程中使用它們。在沒有發布之前,作為異步編程主力軍的回調函數一直被人詬病,其原因有太多比如回調地獄代碼執行順序難以追蹤后期因代碼變得十分復雜導致無法維護和更新等,而的出現在很大程度上改變了之前的窘境。 前言 自己著手準備寫這篇文章的初衷是覺得如果想要更深入的理解 JS,異步編程則是必須要跨過的一道坎。由于這里面涉及到的東西很多也很廣,在初學 JS 的...

    lordharrd 評論0 收藏0
  • [ JS 進階 ] 異步編程 promise模式 的簡單實現

    摘要:為了降低異步編程的復雜性,所以。難理解請參考的誤區以及實踐異步編程的模式異步編程的種方法 異步編程 javascript異步編程, web2.0時代比較熱門的編程方式,我們平時碼的時候也或多或少用到,最典型的就是異步ajax,發送異步請求,綁定回調函數,請求響應之后調用指定的回調函數,沒有阻塞其他代碼的執行。還有像setTimeout方法同樣也是異步執行回調的方法。 如果對異步編程...

    svtter 評論0 收藏0

發表評論

0條評論

diabloneo

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<