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

資訊專欄INFORMATION COLUMN

你不知道的JavaScript :Promise 與 Async/Await

wmui / 2135人閱讀

摘要:前言對(duì)于這門語(yǔ)言,其實(shí)我更喜歡稱它為,從一開(kāi)始我們就已經(jīng)涉及到異步編程,但是多數(shù)開(kāi)發(fā)者從來(lái)沒(méi)有認(rèn)真思考過(guò)自己程序中的異步,到底是怎么實(shí)現(xiàn)的,以及為什么會(huì)出現(xiàn)。

前言

對(duì)于JavaScript這門語(yǔ)言,其實(shí)我更喜歡稱它為ECMAScript,從一開(kāi)始我們就已經(jīng)涉及到異步編程,但是多數(shù)JavaScript開(kāi)發(fā)者從來(lái)沒(méi)有認(rèn)真思考過(guò)自己程序中的異步,到底是怎么實(shí)現(xiàn)的,以及為什么會(huì)出現(xiàn)。但是由于開(kāi)發(fā)者對(duì)JavaScript的需求和項(xiàng)目的復(fù)雜程度日漸擴(kuò)大,特別是對(duì)異步的管理越來(lái)越令人痛苦,這一切導(dǎo)致我們迫切需要更加強(qiáng)大、更加合理的異步方法,幫我們管理異步的狀態(tài)。

開(kāi)始

在JavaScript異步編程歷史上,我認(rèn)為一共出現(xiàn)了三種異步編程方式

回調(diào)

Promise

Async/Await

由于我不想回憶起很久以前,被回調(diào)地獄支配的恐懼,就跳過(guò)回調(diào)這一塊,讀者們自行了解(篇幅有限)
(PS:好吧,new Date() --> Sat May 19 2018 23:55:17 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間),寫完洗洗睡吧)

Promise 什么是Promise

Promise是一種范式。在這里扯一句:回調(diào)是將我們封裝的回調(diào)函數(shù)交給第三方(甚至可能是外部代碼),緊接著我們期待它能夠調(diào)用我們封裝的回調(diào)函數(shù)。那么Promise就是不把自己的程序傳遞給第三方,而是第三方給我們提供此任務(wù)何時(shí)結(jié)束,然后由我們自己決定下一步做什么

設(shè)想一個(gè)場(chǎng)景,今天早上,我去買早餐,到了一個(gè)快餐店,點(diǎn)了一個(gè)漢堡做了一次請(qǐng)求),我就在收銀臺(tái)上支付了這個(gè)漢堡的價(jià)格類似于參數(shù)的傳遞),但是我并沒(méi)有立即得到這個(gè)漢堡,而是拿到了一個(gè)訂單號(hào),這個(gè)時(shí)候我就只需要坐著等待小姐姐叫到我的訂單號(hào)(這個(gè)時(shí)候已經(jīng)產(chǎn)生了一個(gè)Promise),在這個(gè)中間等待的時(shí)間,我們可以做一些其他的事情,比如打電話、玩兒手機(jī)、談工作等等......(這就是合理利用中間的空隙時(shí)間,在js的異步中也可以完全體現(xiàn),但不在本文的探討范圍內(nèi)),直到小姐姐叫到XX號(hào)碼的好了(一個(gè)Promise執(zhí)行結(jié)束),結(jié)果一般有兩種,要么是漢堡做好了Promise中的resolve()中設(shè)置的值),要么是漢堡賣完了(Promise中的reject()中設(shè)置的值),這時(shí)我就需要考慮換其他食物了。假設(shè)漢堡做好了,我再過(guò)去拿我的漢堡,拿到過(guò)后,我可以自行選擇吃掉它或者是扔掉它(當(dāng)然這是不可能的)(這就體現(xiàn)了具體怎么實(shí)現(xiàn)的決定權(quán)在我們)
這個(gè)例子我覺(jué)得還是很形象的,哈哈哈。
如何創(chuàng)建并使用一個(gè)Promise

首先我先告訴你Promise的決議結(jié)果resovle完成reject拒絕

  // -----------------------> Promise 的創(chuàng)建與使用
  function creat_promise () {
    return new Promise((resolve, reject) => {
      resolve(42)
    })
  }
  function use_promise () {
    const a_promise = creat_promise()
    a_promise.then(res => console.log(res))
  }
  use_promise()
Promise的高級(jí)使用方法

當(dāng)你看到這一節(jié)時(shí),需要用到自定義的模擬數(shù)據(jù)請(qǐng)求類
該api類在這兒
或者查看本項(xiàng)目的源碼,配合著瀏覽本文章

// api.js
// 定義初始數(shù)據(jù)
const users = [
  { id: 1, name: "jack", year: 12, grade: 1 },
  { id: 2, name: "john", year: 12, grade: 1 },
  { id: 3, name: "winer", year: 12, grade: 2 }
]

// user的father,根據(jù)child鏈接
const fathers = [
  {id: 11, child: "jack", name: "jack_father"},
  {id: 22, child: "john", name: "john_father"},
  {id: 33, child: "winer", name: "winer_father"}
]

class Api {
  // 根據(jù)id獲取一個(gè)User對(duì)象的Promise
  getUserById (id, request_time = 1000, fn = function () {}) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        const user = users.find(item => {
          return item.id === id
        })
        fn()
        resolve(user)
      }, request_time)
    })
  }
  // 根據(jù)grade獲取一個(gè)User對(duì)象列表的Promise
  getUsersByGrade (grade) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        const _users = users.filter(item => {
          return item.grade === grade
        })
        resolve(_users)
      }, 1000)
    })
  }
  // 根據(jù)user獲取一個(gè)UserName的Promise
  getUserName (user, request_time = 1000) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        const child = users.find(item => {
          return item.name === user.name
        })
        resolve(child.name)
      }, request_time)
    })
  }
  // 根據(jù)userName獲取一個(gè)Father的Promise
  getFatherByChildName (childName) {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        const father = fathers.find(item => {
          return item.child === childName
        })
        resolve(father)
      }, 1000)
    })
  }
  // 拋出一個(gè)異常的Promise
  throw_Error () {
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        reject(new Error("api.js-------->拋出了一個(gè)錯(cuò)誤"))
      }, 1000)
    })
  }
}

首先 const api = new Api()

Promise 的鏈?zhǔn)巾樞蚰J?/p>

// -----------------------> Promise 的鏈?zhǔn)巾樞蚰J?  function promise_chain () {
    api.getUserById(1)
      .then(res => {
        console.log(res)
        return api.getUserName(res)
      })
      .then(res => {
        console.log(res)
        return api.getFatherByChildName(res)
      })
      .then(res => console.log(res))
  }
  promise_chain()

每個(gè)Promise.then(..)中的返回值(即使返回的不是Promise對(duì)象,因?yàn)镻romise內(nèi)在機(jī)制會(huì)將其轉(zhuǎn)換為一個(gè)可以使用的Promise)將會(huì)作為下一個(gè)Promise對(duì)象,即Promise.then( return ...)得到的是一個(gè)Promise對(duì)象,因此可以不斷地Promise.then( return ... ).then( return ... ).then( return ... ).then( return ... ).then( return ... ).then()......

Promise 的catch

function promise_lastErro () {
    api.throw_Error()
    .then(res => console.log("沒(méi)有錯(cuò)"))
    .catch(err => {
      console.log(err)
      foo.bar()
    })
    console.log("無(wú)法捕捉最后一個(gè)catch的錯(cuò)誤:foo.bar()")
  }
  promise_lastErro()

Promise 的并發(fā)/并行 : Promise.all([...])
傳入的參數(shù)是一個(gè)Promise的數(shù)組
如果傳入的是[],Promise.all([...])將立即決議為完成
全部Promise完成,Promise.all([...])完成
如果有一個(gè)被拒絕,則Promise.all([...])被拒絕

function promise_concurrent_1 () {
    const p1 = api.getUserById(1,Math.random() * 1000, () => { console.log("p1執(zhí)行完畢") })
    const p2 = api.getUserById(1,Math.random() * 1000, () => { console.log("p2執(zhí)行完畢") })
    Promise.all([p1, p2])
      .then(res => console.log("p1 p2 都執(zhí)行完畢"))
  }
  promise_concurrent_1()

Promise 的任務(wù)競(jìng)爭(zhēng):競(jìng)態(tài)(第一優(yōu)先) : Promise.race([...])
傳入的參數(shù)是一個(gè)Promise的數(shù)組
如果傳入的是[],Promise.race([...])將不會(huì)決議,始終處于掛起狀態(tài)
只要有一個(gè)Primise完成,Promise.race([...])則完成
如果有一個(gè)被拒絕,則Promise.race([...])被拒絕

function promise_compete () {
    const p1 = api.getUserById(1, 2000)
    const p2 = api.getUserById(2)
    Promise.race([p1, p2]).then(res => console.log(res))
  }
  promise_compete()

關(guān)于Promise.all([...])與Promise.race([...])的變體有很多

Promise.none([...]): 要求[...]全部被拒絕,Promise.none([...])決議為完成

Promise.any([...]): 與Promise.all([...])類似,但只要求完成一個(gè)即可,但是會(huì)執(zhí)行所有Promise

Promise.first([...]):與Promise.any([...])類似,但是只要有第一個(gè)Promise決議為完成,就不關(guān)心后面的Promise

Promise.last([...]):與Promise.first([...])相反,最后一個(gè)完成的勝出

到此Promise的基本用法就是這些了吧,不知不覺(jué)半個(gè)小時(shí)過(guò)去了。

Async/Await 什么是Async/Await

我認(rèn)為Async/Await是區(qū)別于Promise更優(yōu)雅的體現(xiàn),它可以簡(jiǎn)化Promise的大部分代碼,讓你的代碼看上去優(yōu)雅美觀并且大氣。并且我支持你,在現(xiàn)在甚至以后,對(duì)異步的管理盡可能使用Async/Await。

Async/Await的使用

使用Async/Await代替鏈?zhǔn)絧romise(類比 ---> Promise的鏈?zhǔn)巾樞蚰J?

async function async_Request () {
    console.log("請(qǐng)稍等..此時(shí)是三個(gè)setTimeOut,每個(gè)1s,需要等待3s")
    const user = await api.getUserById(1)
    const userName = await api.getUserName(user)
    const father = await api.getFatherByChildName(userName)
    console.log(father)
}
async_Request()

使用Async/Await的并發(fā)與并行

async function async_Concurrent () {
    const users = await api.getUsersByGrade(1)
    const usersPromise = users.map(item => api.getUserName(item, Math.random() * 1000))
    Promise.all(usersPromise).then(res => {
      console.log(res)
    })
}
async_Concurrent()

使用Async/Await的錯(cuò)誤捕捉

async function async_CatchErro () {
  try {
    await api.throw_Error()
    console.log("未捕捉到錯(cuò)誤?")
  } catch (error) {
    console.log(error)
  }
}
async_CatchErro()

Async/Await函數(shù)的互相調(diào)用

async function async_A () {
    const user = await api.getUserById(2)
    const userName = await api.getUserName(user)
    const father = await api.getFatherByChildName(userName)
    return { user, userName, father }
}
async function async_B () {
    console.log("數(shù)據(jù)獲取中...")
    const { user, userName, father } = await async_A()
    console.log("userInfo",{ user, userName, father })
}
async_B()

Async/Await檢索十條數(shù)據(jù),串行

async function async_ten_serial (length = 10) {
    try {
      const users = []
      console.log("串行請(qǐng)求10條數(shù)據(jù),每條1秒,請(qǐng)稍等10秒鐘....")
      while(users.length < 10) {
        users.push(await api.getUserById(1))
      }
      console.log(users)
    } catch (error) {
      console.log(error)
    }
}
async_ten_serial()

Async/Await檢索十條數(shù)據(jù),并行

async function async_ten_parallel (length = 10) {
    try {
      const usersPromise = []
      console.log("并行請(qǐng)求10條數(shù)據(jù),每條1秒,請(qǐng)稍等1秒鐘....")
      while(usersPromise.length < 10) {
        usersPromise.push(api.getUserById(2))
      }
      const users = await Promise.all(usersPromise)
      console.log(users)
    } catch (error) {
      console.log(error)
    }
}
async_ten_parallel()

ok!本文并沒(méi)有講那些概念性的東西,只是簡(jiǎn)單地講這幾種實(shí)現(xiàn)用代碼描述出來(lái),更詳細(xì)的。請(qǐng)大家參考官方文檔,其實(shí)對(duì)于這篇文章的排版,我發(fā)現(xiàn)應(yīng)該將PromiseAsync/Await對(duì)比起來(lái)描述,懶得重新排版了,委屈各位手動(dòng)對(duì)比了。(:
源碼地址
(PS: newDate() ---> Sun May 20 2018 00:42:15 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間))
不知不覺(jué)竟然寫了接近一個(gè)小時(shí),溜了溜了,不修仙。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/95122.html

相關(guān)文章

  • JS 異步編程六種方案

    摘要:接下來(lái)介紹下異步編程六種方法。六生成器函數(shù)是提供的一種異步編程解決方案,語(yǔ)法行為與傳統(tǒng)函數(shù)完全不同,最大的特點(diǎn)就是可以控制函數(shù)的執(zhí)行。參考文章前端面試之道異步編程的種方法你不知道的中卷函數(shù)的含義和用法替代的個(gè)理由 前言 我們知道Javascript語(yǔ)言的執(zhí)行環(huán)境是單線程。也就是指一次只能完成一件任務(wù)。如果有多個(gè)任務(wù),就必須排隊(duì),前面一個(gè)任務(wù)完成,再執(zhí)行后面一個(gè)任務(wù)。 這種模式雖然實(shí)現(xiàn)起...

    longmon 評(píng)論0 收藏0
  • JavaScript基礎(chǔ)——深入學(xué)習(xí)async/await

    摘要:等待的基本語(yǔ)法該關(guān)鍵字的的意思就是讓編譯器等待并返回結(jié)果。這里并不會(huì)占用資源,因?yàn)橐婵梢酝瑫r(shí)執(zhí)行其他任務(wù)其他腳本或處理事件。接下來(lái),我們寫一個(gè)火箭發(fā)射場(chǎng)景的小例子不是真的發(fā)射火箭 本文由云+社區(qū)發(fā)表 本篇文章,小編將和大家一起學(xué)習(xí)異步編程的未來(lái)——async/await,它會(huì)打破你對(duì)上篇文章Promise的認(rèn)知,竟然異步代碼還能這么寫! 但是別太得意,你需要深入理解Promise后,...

    張金寶 評(píng)論0 收藏0
  • 最后一次搞懂 Event Loop

    摘要:由于是單線程的,這些方法就會(huì)按順序被排列在一個(gè)單獨(dú)的地方,這個(gè)地方就是所謂執(zhí)行棧。事件隊(duì)列每次僅執(zhí)行一個(gè)任務(wù),在該任務(wù)執(zhí)行完畢之后,再執(zhí)行下一個(gè)任務(wù)。 Event Loop 是 JavaScript 異步編程的核心思想,也是前端進(jìn)階必須跨越的一關(guān)。同時(shí),它又是面試的必考點(diǎn),特別是在 Promise 出現(xiàn)之后,各種各樣的面試題層出不窮,花樣百出。這篇文章從現(xiàn)實(shí)生活中的例子入手,讓你徹底理解 E...

    gself 評(píng)論0 收藏0
  • JavaScript工作原理(四):事件循環(huán),異步編程興起以及5招async/await實(shí)踐

    摘要:事件循環(huán)從回調(diào)隊(duì)列中獲取并將其推送到調(diào)用堆棧。如何工作請(qǐng)注意,不會(huì)自動(dòng)將您的回調(diào)函數(shù)放到事件循環(huán)隊(duì)列中。它設(shè)置了一個(gè)計(jì)時(shí)器,當(dāng)計(jì)時(shí)器到期時(shí),環(huán)境將您的回調(diào)函數(shù)放入事件循環(huán)中,以便將來(lái)的某個(gè)事件會(huì)將其選中并執(zhí)行它。 我們將通過(guò)回顧第一篇文章中單線程編程的缺點(diǎn),然后在討論如何克服它們來(lái)構(gòu)建令人驚嘆的JavaScript UI。在文章結(jié)尾處,我們將分享5個(gè)關(guān)于如何使用async / awai...

    piglei 評(píng)論0 收藏0
  • async/await 更好異步解決方案

    摘要:大家都一直在嘗試使用更好的方案來(lái)解決這些問(wèn)題。這是一個(gè)用同步的思維來(lái)解決異步問(wèn)題的方案。當(dāng)我們發(fā)出了請(qǐng)求,并不會(huì)等待響應(yīng)結(jié)果,而是會(huì)繼續(xù)執(zhí)行后面的代碼,響應(yīng)結(jié)果的處理在之后的事件循環(huán)中解決。我們可以用一個(gè)兩人問(wèn)答的場(chǎng)景來(lái)比喻異步與同步。 在實(shí)際開(kāi)發(fā)中總會(huì)遇到許多異步的問(wèn)題,最常見(jiàn)的場(chǎng)景便是接口請(qǐng)求之后一定要等一段時(shí)間才能得到結(jié)果,如果遇到多個(gè)接口前后依賴,那么問(wèn)題就變得復(fù)雜。大家都一直...

    Ali_ 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<