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

資訊專欄INFORMATION COLUMN

異步解決方案----Promise與Await

entner / 3267人閱讀

摘要:前言異步編程模式在前端開發(fā)過程中,顯得越來越重要。隨著新標(biāo)準(zhǔn)的到來,處理異步數(shù)據(jù)流又有了新的方案。接下來我們介紹這兩種處理異步編程的方案。仍在繼續(xù)執(zhí)行,但執(zhí)行結(jié)果將被丟棄。使得異步代碼看起來像同步代碼,再也沒有回調(diào)函數(shù)。

前言

異步編程模式在前端開發(fā)過程中,顯得越來越重要。從最開始的XHR到封裝后的Ajax都在試圖解決異步編程過程中的問題。隨著ES6新標(biāo)準(zhǔn)的到來,處理異步數(shù)據(jù)流又有了新的方案。我們都知道,在傳統(tǒng)的ajax請(qǐng)求中,當(dāng)異步請(qǐng)求之間的數(shù)據(jù)存在依賴關(guān)系的時(shí)候,就可能產(chǎn)生很難看的多層回調(diào),俗稱"回調(diào)地獄"(callback hell),這卻讓人望而生畏,Promise的出現(xiàn)讓我們告別回調(diào)函數(shù),寫出更優(yōu)雅的異步代碼。在實(shí)踐過程中,卻發(fā)現(xiàn)Promise并不完美,Async/Await是近年來JavaScript添加的最革命性的的特性之一,Async/Await提供了一種使得異步代碼看起來像同步代碼的替代方法。接下來我們介紹這兩種處理異步編程的方案。

一、Promise的原理與基本語法 1.Promise的原理

Promise 是一種對(duì)異步操作的封裝,可以通過獨(dú)立的接口添加在異步操作執(zhí)行成功、失敗時(shí)執(zhí)行的方法。主流的規(guī)范是 Promises/A+。

Promise中有幾個(gè)狀態(tài)

pending: 初始狀態(tài), 非 fulfilled 或 rejected;

fulfilled: 成功的操作,為表述方便,fulfilled 使用 resolved 代替;

rejected: 失敗的操作。

pending可以轉(zhuǎn)化為fulfilled或rejected并且只能轉(zhuǎn)化一次,也就是說如果pending轉(zhuǎn)化到fulfilled狀態(tài),那么就不能再轉(zhuǎn)化到rejected。并且fulfilled和rejected狀態(tài)只能由pending轉(zhuǎn)化而來,兩者之間不能互相轉(zhuǎn)換。

2.Promise的基本語法

Promise實(shí)例必須實(shí)現(xiàn)then這個(gè)方法

then()必須可以接收兩個(gè)函數(shù)作為參數(shù)

then()返回的必須是一個(gè)Promise實(shí)例

//如果低版本瀏覽器不支持Promise,通過cdn這種方式
      
二、Promise多個(gè)串聯(lián)操作

Promise還可以做更多的事情,比如,有若干個(gè)異步任務(wù),需要先做任務(wù)1,如果成功后再做任務(wù)2,任何任務(wù)失敗則不再繼續(xù)并執(zhí)行錯(cuò)誤處理函數(shù)。要串行執(zhí)行這樣的異步任務(wù),不用Promise需要寫一層一層的嵌套代碼。

有了Promise,我們只需要簡(jiǎn)單地寫job1.then(job2).then(job3).catch(handleError);
其中job1、job2和job3都是Promise對(duì)象。

比如我們想實(shí)現(xiàn)第一個(gè)圖片加載完成后,再加載第二個(gè)圖片,如果其中有一個(gè)執(zhí)行失敗,就執(zhí)行錯(cuò)誤函數(shù):

       var src1 = "https://www.imooc.com/static/img/index/logo_new.png"
        var result1 = loadImg(src1) //result1是Promise對(duì)象
        var src2 = "https://img1.mukewang.com/545862fe00017c2602200220-100-100.jpg"
        var result2 = loadImg(src2) //result2是Promise對(duì)象
        result1.then(function (img1) {
            console.log("第一個(gè)圖片加載完成", img1.width)
            return result2  // 鏈?zhǔn)讲僮?        }).then(function (img2) {
            console.log("第二個(gè)圖片加載完成", img2.width)
        }).catch(function (ex) {
            console.log(ex)
        })

這里需注意的是:then 方法可以被同一個(gè) promise 調(diào)用多次,then 方法必須返回一個(gè) promise 對(duì)象。上例中result1.then如果沒有明文返回Promise實(shí)例,就默認(rèn)為本身Promise實(shí)例即result1,result1.then返回了result2實(shí)例,后面再執(zhí)行.then實(shí)際上執(zhí)行的是result2.then

三、Promise常用方法

除了串行執(zhí)行若干異步任務(wù)外,Promise還可以并行執(zhí)行異步任務(wù)

試想一個(gè)頁面聊天系統(tǒng),我們需要從兩個(gè)不同的URL分別獲得用戶的個(gè)人信息和好友列表,這兩個(gè)任務(wù)是可以并行執(zhí)行的,用Promise.all()實(shí)現(xiàn)如下:

var p1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, "P1");
});
var p2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, "P2");
});
// 同時(shí)執(zhí)行p1和p2,并在它們都完成后執(zhí)行then:
Promise.all([p1, p2]).then(function (results) {
    console.log(results); // 獲得一個(gè)Array: ["P1", "P2"]
});

有些時(shí)候,多個(gè)異步任務(wù)是為了容錯(cuò)。比如,同時(shí)向兩個(gè)URL讀取用戶的個(gè)人信息,只需要獲得先返回的結(jié)果即可。這種情況下,用Promise.race()實(shí)現(xiàn):

var p1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, "P1");
});
var p2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, "P2");
});
Promise.race([p1, p2]).then(function (result) {
    console.log(result); // "P1"
});

由于p1執(zhí)行較快,Promise的then()將獲得結(jié)果"P1"。p2仍在繼續(xù)執(zhí)行,但執(zhí)行結(jié)果將被丟棄。

總結(jié):Promise.all接受一個(gè)promise對(duì)象的數(shù)組,待全部完成之后,統(tǒng)一執(zhí)行success;

Promise.race接受一個(gè)包含多個(gè)promise對(duì)象的數(shù)組,只要有一個(gè)完成,就執(zhí)行success

接下來我們對(duì)上面的例子做下修改,加深對(duì)這兩者的理解:

     var src1 = "https://www.imooc.com/static/img/index/logo_new.png"
     var result1 = loadImg(src1)
     var src2 = "https://img1.mukewang.com/545862fe00017c2602200220-100-100.jpg"
     var result2 = loadImg(src2)
     Promise.all([result1, result2]).then(function (datas) {
         console.log("all", datas[0])//
         console.log("all", datas[1])//
     })
     Promise.race([result1, result2]).then(function (data) {
         console.log("race", data)//
     })

如果我們組合使用Promise,就可以把很多異步任務(wù)以并行和串行的方式組合起來執(zhí)行

四、Async/Await簡(jiǎn)介與用法

異步操作是 JavaScript 編程的麻煩事,很多人認(rèn)為async函數(shù)是異步操作的終極解決方案。

1、Async/Await簡(jiǎn)介

async/await是寫異步代碼的新方式,優(yōu)于回調(diào)函數(shù)和Promise。

async/await是基于Promise實(shí)現(xiàn)的,它不能用于普通的回調(diào)函數(shù)。

async/await與Promise一樣,是非阻塞的。

async/await使得異步代碼看起來像同步代碼,再也沒有回調(diào)函數(shù)。但是改變不了JS單線程、異步的本質(zhì)。

2、Async/Await的用法

使用await,函數(shù)必須用async標(biāo)識(shí)

await后面跟的是一個(gè)Promise實(shí)例

需要安裝babel-polyfill,安裝后記得引入 //npm i --save-dev babel-polyfill

   function loadImg(src) {
            const promise = new Promise(function (resolve, reject) {
                const img = document.createElement("img")
                img.onload = function () {
                    resolve(img)
                }
                img.onerror = function () {
                    reject("圖片加載失敗")
                }
                img.src = src
            })
            return promise
        }
     const src1 = "https://www.imooc.com/static/img/index/logo_new.png"
     const src2 = "https://img1.mukewang.com/545862fe00017c2602200220-100-100.jpg"
     const load = async function(){
        const result1 = await loadImg(src1)
        console.log(result1)
        const result2 = await loadImg(src2)
        console.log(result2) 
     }
     load()

當(dāng)函數(shù)執(zhí)行的時(shí)候,一旦遇到 await 就會(huì)先返回,等到觸發(fā)的異步操作完成,再接著執(zhí)行函數(shù)體內(nèi)后面的語句。

五、Async/Await錯(cuò)誤處理

await 命令后面的 Promise 對(duì)象,運(yùn)行結(jié)果可能是 rejected,所以最好把 await 命令放在 try...catch 代碼塊中。try..catch錯(cuò)誤處理也比較符合我們平常編寫同步代碼時(shí)候處理的邏輯

async function myFunction() {
  try {
    await somethingThatReturnsAPromise();
  } catch (err) {
    console.log(err);
  }
}
六、為什么Async/Await更好?

Async/Await較Promise有諸多好處,以下介紹其中三種優(yōu)勢(shì):

1. 簡(jiǎn)潔

使用Async/Await明顯節(jié)約了不少代碼。我們不需要寫.then,不需要寫匿名函數(shù)處理Promise的resolve值,也不需要定義多余的data變量,還避免了嵌套代碼。

2. 中間值

你很可能遇到過這樣的場(chǎng)景,調(diào)用promise1,使用promise1返回的結(jié)果去調(diào)用promise2,然后使用兩者的結(jié)果去調(diào)用promise3。你的代碼很可能是這樣的:

const makeRequest = () => {
  return promise1()
    .then(value1 => {
      return promise2(value1)
        .then(value2 => {        
          return promise3(value1, value2)
        })
    })
}

使用async/await的話,代碼會(huì)變得異常簡(jiǎn)單和直觀

const makeRequest = async () => {
  const value1 = await promise1()
  const value2 = await promise2(value1)
  return promise3(value1, value2)
}
3.條件語句

下面示例中,需要獲取數(shù)據(jù),然后根據(jù)返回?cái)?shù)據(jù)決定是直接返回,還是繼續(xù)獲取更多的數(shù)據(jù)。

const makeRequest = () => {
  return getJSON()
    .then(data => {
      if (data.needsAnotherRequest) {
        return makeAnotherRequest(data)
          .then(moreData => {
            console.log(moreData)
            return moreData
          })
      } else {
        console.log(data)
        return data
      }
    })
}

代碼嵌套(6層)可讀性較差,它們傳達(dá)的意思只是需要將最終結(jié)果傳遞到最外層的Promise。使用async/await編寫可以大大地提高可讀性:

const makeRequest = async () => {
  const data = await getJSON()
  if (data.needsAnotherRequest) {
    const moreData = await makeAnotherRequest(data);
    console.log(moreData)
    return moreData
  } else {
    console.log(data)
    return data    
  }
}

如果覺得文章對(duì)你有些許幫助,歡迎在我的GitHub博客點(diǎn)贊和關(guān)注,感激不盡!

參考文章

Async/Await替代Promise的6個(gè)理由

前端的異步解決方案之Promise和Await/Async

廖雪峰的Javascript教程

[[譯] Promises/A+ 規(guī)范](http://www.ituring.com.cn/art...

async 函數(shù)的含義和用法

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

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

相關(guān)文章

  • 異步解決方案----PromiseAwait

    摘要:前言異步編程模式在前端開發(fā)過程中,顯得越來越重要。隨著新標(biāo)準(zhǔn)的到來,處理異步數(shù)據(jù)流又有了新的方案。接下來我們介紹這兩種處理異步編程的方案。仍在繼續(xù)執(zhí)行,但執(zhí)行結(jié)果將被丟棄。使得異步代碼看起來像同步代碼,再也沒有回調(diào)函數(shù)。 前言 異步編程模式在前端開發(fā)過程中,顯得越來越重要。從最開始的XHR到封裝后的Ajax都在試圖解決異步編程過程中的問題。隨著ES6新標(biāo)準(zhǔn)的到來,處理異步數(shù)據(jù)流又有了新...

    Blackjun 評(píng)論0 收藏0
  • 異步解決方案----PromiseAwait

    摘要:前言異步編程模式在前端開發(fā)過程中,顯得越來越重要。隨著新標(biāo)準(zhǔn)的到來,處理異步數(shù)據(jù)流又有了新的方案。接下來我們介紹這兩種處理異步編程的方案。仍在繼續(xù)執(zhí)行,但執(zhí)行結(jié)果將被丟棄。使得異步代碼看起來像同步代碼,再也沒有回調(diào)函數(shù)。 前言 異步編程模式在前端開發(fā)過程中,顯得越來越重要。從最開始的XHR到封裝后的Ajax都在試圖解決異步編程過程中的問題。隨著ES6新標(biāo)準(zhǔn)的到來,處理異步數(shù)據(jù)流又有了新...

    Neilyo 評(píng)論0 收藏0
  • ES6-7

    摘要:的翻譯文檔由的維護(hù)很多人說,阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會(huì)promise...... 本書的目的是以目前還在制定中的ECMASc...

    mudiyouyou 評(píng)論0 收藏0
  • 現(xiàn)代JS中的流程控制:詳解Callbacks 、Promises 、Async/Await

    摘要:控制臺(tái)將顯示回調(diào)地獄通常,回調(diào)只能由一個(gè)異步函數(shù)調(diào)用。更多資源使更友好規(guī)范使用異步函數(shù)簡(jiǎn)化異步編碼旅程異步編程是一項(xiàng)在中無法避免的挑戰(zhàn)。 JavaScript經(jīng)常聲稱是_異步_。那是什么意思?它如何影響發(fā)展?近年來這種方法有何變化? 請(qǐng)思考以下代碼: result1 = doSomething1(); result2 = doSomething2(result1); 大多數(shù)語言都處理每...

    shadowbook 評(píng)論0 收藏0
  • 現(xiàn)代JS中的流程控制:詳解Callbacks 、Promises 、Async/Await

    摘要:控制臺(tái)將顯示回調(diào)地獄通常,回調(diào)只能由一個(gè)異步函數(shù)調(diào)用。更多資源使更友好規(guī)范使用異步函數(shù)簡(jiǎn)化異步編碼旅程異步編程是一項(xiàng)在中無法避免的挑戰(zhàn)。 JavaScript經(jīng)常聲稱是_異步_。那是什么意思?它如何影響發(fā)展?近年來這種方法有何變化? 請(qǐng)思考以下代碼: result1 = doSomething1(); result2 = doSomething2(result1); 大多數(shù)語言都處理每...

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

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

0條評(píng)論

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