成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

js 異步編程

diabloneo / 455人閱讀

摘要:總結(jié)這篇文章簡單的介紹了一些常用的異步編程的方法,如果有錯誤或不嚴(yán)謹(jǐn)?shù)牡胤剑瑲g迎批評指正,如果喜歡,歡迎點贊收藏。

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

回調(diào)函數(shù)

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

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

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

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

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

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")
  })

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

Async

在正式使用異步函數(shù)之前,先簡單的介紹一下它的用法,async通常與await一起使用,async函數(shù)返回一個Promise對象,可以使用then方法添加回調(diào)函數(shù)。當(dāng)函數(shù)執(zhí)行的時候,一旦遇到await就會先返回,等到觸發(fā)的異步操作完成,再接著執(zhí)行函數(shù)體后面的語句。做了簡單的介紹后,接下來,我們來async函數(shù)是怎么對Promise調(diào)用優(yōu)化的??聪旅娴睦樱?/p>

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

錯誤捕獲

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

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()

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

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異步函數(shù)的錯誤處理封裝到了一個to.js中,這里面其實只有一個簡單方法,傳入一個Promise對象,對Promise對象進行錯誤捕獲返回值,用解構(gòu)的形式獲取返回值和錯誤,這樣就不需要反復(fù)寫try catche做錯誤捕獲了。to.js是一個開源庫

異步陷阱

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

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()

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

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()方法,將所有異步操作作為參數(shù)數(shù)組傳入,這樣print("a")、print("b")、print("c")、print("d")這四個異步操作就可以并發(fā)執(zhí)行了。

總結(jié)

這篇文章簡單的介紹了一些常用的異步編程的方法,如果有錯誤或不嚴(yán)謹(jǐn)?shù)牡胤?,歡迎批評指正,如果喜歡,歡迎點贊收藏。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/98835.html

相關(guān)文章

  • js學(xué)習(xí)之異步處理

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

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

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

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

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

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

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

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

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

    svtter 評論0 收藏0

發(fā)表評論

0條評論

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