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

資訊專欄INFORMATION COLUMN

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

wmui / 2142人閱讀

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

前言

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

開始

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

回調(diào)

Promise

Async/Await

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

Promise 什么是Promise

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

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

當(dāng)你看到這一節(jié)時(shí),需要用到自定義的模擬數(shù)據(jù)請求類
該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對象的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對象列表的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對象,因?yàn)镻romise內(nèi)在機(jī)制會將其轉(zhuǎn)換為一個(gè)可以使用的Promise)將會作為下一個(gè)Promise對象,即Promise.then( return ...)得到的是一個(gè)Promise對象,因此可以不斷地Promise.then( return ... ).then( return ... ).then( return ... ).then( return ... ).then( return ... ).then()......

Promise 的catch

function promise_lastErro () {
    api.throw_Error()
    .then(res => console.log("沒有錯(cuò)"))
    .catch(err => {
      console.log(err)
      foo.bar()
    })
    console.log("無法捕捉最后一個(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ù)競爭:競態(tài)(第一優(yōu)先) : Promise.race([...])
傳入的參數(shù)是一個(gè)Promise的數(shù)組
如果傳入的是[],Promise.race([...])將不會決議,始終處于掛起狀態(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è)即可,但是會執(zhí)行所有Promise

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

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

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

Async/Await 什么是Async/Await

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

Async/Await的使用

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

async function async_Request () {
    console.log("請稍等..此時(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("串行請求10條數(shù)據(jù),每條1秒,請稍等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("并行請求10條數(shù)據(jù),每條1秒,請稍等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!本文并沒有講那些概念性的東西,只是簡單地講這幾種實(shí)現(xiàn)用代碼描述出來,更詳細(xì)的。請大家參考官方文檔,其實(shí)對于這篇文章的排版,我發(fā)現(xiàn)應(yīng)該將PromiseAsync/Await對比起來描述,懶得重新排版了,委屈各位手動(dòng)對比了。(:
源碼地址
(PS: newDate() ---> Sun May 20 2018 00:42:15 GMT+0800 (中國標(biāo)準(zhǔn)時(shí)間))
不知不覺竟然寫了接近一個(gè)小時(shí),溜了溜了,不修仙。

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

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

相關(guān)文章

  • JS 異步編程六種方案

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

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

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

    張金寶 評論0 收藏0
  • 最后一次搞懂 Event Loop

    摘要:由于是單線程的,這些方法就會按順序被排列在一個(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 評論0 收藏0
  • JavaScript工作原理(四):事件循環(huán),異步編程興起以及5招async/await實(shí)踐

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

    piglei 評論0 收藏0
  • async/await 更好異步解決方案

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

    Ali_ 評論0 收藏0

發(fā)表評論

0條評論

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