promise async await使用

1.Promise

(名字含義:promise爲承諾,表示其餘手段沒法改變)javascript

Promise 對象表明一個異步操做,其不受外界影響,有三種狀態:
  • Pending(進行中、未完成的)
  • Resolved(已完成,又稱 Fulfilled)
  • Rejected(已失敗)

promises的優點

1.解決回調地獄php

2.更好地進行錯誤捕獲css

有時咱們要進行一些相互間有依賴關係的異步操做,好比有多個請求,後一個的請求須要上一次請求的返回結果。過去常規作法只能 callback 層層嵌套,但嵌套層數過多的話就會有 callback hell 問題。好比下面代碼,可讀性和維護性都不好的。html

firstAsync(function(data){
    //處理獲得的 data 數據
    //....
    secondAsync(function(data2){
        //處理獲得的 data2 數據
        //....
        thirdAsync(function(data3){
              //處理獲得的 data3 數據
              //....
        });
    });
});

 

promise例子1前端

//建立一個Promise實例,獲取數據。並把數據傳遞給處理函數resolve和reject。須要注意的是Promise在聲明的時候就執行了。
var getUserInfo=new Promise(function(resolve,reject){
    $.ajax({
        type:"get",
        url:"index.aspx",
        success:function(){
            if(res.code=="ok"){
                resolve(res.msg)//在異步操做成功時調用
            }else{
                reject(res.msg);//在異步操做失敗時調用
            }
        }
    });
})
//另外一個ajax Promise對象,
var getDataList=new Promise(function(resolve,reject){
    $.ajax({
        type:"get",
        url:"index.aspx",
        success:function(res){
            if(res.code=="ok"){
                resolve(res.msg)//在異步操做成功時調用
            }else{
                reject(res.msg);//在異步操做失敗時調用
            }
        }
    });
})
//Promise的方法then,catch方法
getUserInfo.then(function(ResultJson){
    //經過拿到的數據渲染頁面
}).catch(function(ErrMsg){
    //獲取數據失敗時的處理邏輯
})
//Promise的all方法,等數組中的全部promise對象都完成執行
Promise.all([getUserInfo,getDataList]).then(function([ResultJson1,ResultJson2]){
    //這裏寫等這兩個ajax都成功返回數據才執行的業務邏輯
})

注意:成功的結果須要用resolve包裹,失敗的結果須要用reject包裹 vue

 

promise例子2java

ajax請求node

        var getData=new Promise(function(resolve,reject){
          $.post("http://apptest.hcbkeji.com/php/option/activity/chevron_report_activity.php",  {flag: 'click',act:'臨沂頁面',page:'臨沂上報活動'},
            function (res) {
              resolve(res)
            }
          );
        })

        getData.then(res=>{
          console.log(res)   //{"type":"ok"}
        })

promise例子3ios

            var test=new Promise((resolve,reject)=>{
              setTimeout(function(){
                resolve('hello world')
              },2000)
            })
            test.then(res=>{
              console.log(res)
            })
            console.log('雖然在後面,可是我先執行')
            //打印結果
            // 雖然在後面,可是我先執行
            // hello world

promise例子4git

            function mytest(){
              return new Promise((resolve,reject)=>{
                $.post("http://apptest.hcbkeji.com/php/option/activity/chevron_report_activity.php",  {flag: 'click',act:'臨沂頁面',page:'臨沂上報活動'},
                  function (res) {
                    var res=JSON.parse(res)
                    resolve(res)
                  }
                );
              })
            }

            mytest().then(res=>{
              console.log(res)
            })
            console.log('雖然在後面,可是我先執行')

 

 

 

 

2.async

async使用

做爲一個關鍵字放到函數前面,用於表示函數是一個異步函數,由於async就是異步的意思, 異步函數也就意味着該函數的執行不會阻塞後面代碼的執行

調用方法:async 函數也是函數,平時咱們怎麼使用函數就怎麼使用它,直接加方法名括號調用。

 

          async function test(){
            return 'hello world'
          }
          test().then(res=>{
            console.log(res)
          })
          console.log('雖然在後面,可是我先執行')
          //打印結果
          //雖然在後面,可是我先執行
          //hello world

首先打印 ‘雖然在後面,可是我先執行’ ,後執行 打印  ‘hello world’

 

async的做用:輸出的是一個 Promise 對象

async function testAsync() {
 return "hello async";
}
let result = testAsync();
console.log(result)

打印結果Promise {<resolved>: "hello async"}    從結果中能夠看到async函數返回的是一個promise對象,若是在函數中 return 一個直接量,async 會把這個直接量經過 Promise.resolve() 封裝成 Promise 對象。

async function testAsync1() {
 console.log("hello async");
}
let result1 = testAsync1();
console.log(result1);

結果返回Promise.resolve(undefined) 由於使用async 可是函數沒有return一個直接量

 

 async 函數(包含函數語句、函數表達式、Lambda表達式)會返回一個 Promise 對象,若是在函數中 return 一個直接量,async 會把這個直接量經過 Promise.resolve() 封裝成 Promise 對象。

async 函數返回的是一個 Promise 對象,因此在最外層不能用 await 獲取其返回值的狀況下,咱們固然應該用原來的方式:then() 鏈來處理這個 Promise 對象。

Promise 的特色是無等待,因此在沒有 await 的狀況下執行 async 函數,它會當即執行,返回一個 Promise 對象,而且,毫不會阻塞後面的語句。這和普通返回 Promise 對象的函數並沒有二致。

 

 

Promise 有一個resolved,這是async 函數內部的實現原理。若是async 函數中有返回一個值 ,當調用該函數時,內部會調用Promise.solve() 方法把它轉化成一個promise 對象做爲返回,但若是timeout 函數內部拋出錯誤呢? 那麼就會調用Promise.reject() 返回一個promise 對象, 這時修改一下timeout 函數

複製代碼
async function timeout(flag) {
    if (flag) {
        return 'hello world'
    } else {
        throw 'my god, failure'
    }
}
console.log(timeout(true))  // 調用Promise.resolve() 返回promise 對象。
console.log(timeout(false)); // 調用Promise.reject() 返回promise 對象。
複製代碼

  控制檯以下:

  若是函數內部拋出錯誤, promise 對象有一個catch 方法進行捕獲。

timeout(false).catch(err => {
    console.log(err)
})

 

 

 3.await

由於 async 函數返回一個 Promise 對象,因此 await 能夠用於等待一個 async 函數的返回值——這也能夠說是 await 在等 async 函數,但要清楚,它等的實際是一個返回值。注意到 await 不只僅用於等 Promise 對象,它能夠等任意表達式的結果,因此,await 後面實際是能夠接普通函數調用或者promise對象

注意:await 命令只能用在 async 函數之中,若是用在普通函數,就會報錯。

function getSomething() {
    return "something";
}

async function testAsync() {
    return Promise.resolve("hello async");
}

async function test() {
    const v1 = await getSomething();   //await後接普通函數調用
    const v2 = await testAsync();      //await後接async promise對象
    console.log(v1, v2);
}

test();          //打印結果something hello async

await 是個運算符,用於組成表達式,await 表達式的運算結果取決於它等的東西。

若是它等到的不是一個 Promise 對象,那 await 表達式的運算結果就是它等到的東西。

若是它等到的是一個 Promise 對象,await 就忙起來了,它會阻塞後面的代碼,等着 Promise 對象 resolve,而後獲得 resolve 的值,做爲 await 表達式的運算結果。

 await 必須用在 async 函數中的緣由。async 函數調用不會形成阻塞,它內部全部的阻塞都被封裝在一個 Promise 對象中異步執行。

綜合:上面已經說明了 async 會將其後的函數(函數表達式或 Lambda)的返回值封裝成一個 Promise 對象,而 await 會等待這個 Promise 完成,並將其 resolve 的結果返回出來。

 

 

使用promise和async await比較

使用promise

function takeLongTime(n){
  return new Promise(resolve=>{
    setTimeout(()=>resolve(n+200),n)
  })
}

function step1(n){
  console.log(`step1 with ${n}`)
  return takeLongTime(n);
}

function step2(n){
  console.log(`step2 with ${n}`)
  return takeLongTime(n);
}

function step3(n){
  console.log(`step3 with ${n}`)
  return takeLongTime(n);
}


function run(){
  console.time('run')
  const time1=300;
  step1(time1)
    .then(time2=>step2(time2))
    .then(time3=>step3(time3))
    .then(result=>{
      console.log(`resutlt is ${result}`)
      console.timeEnd('run')
    })
}

run()

打印結果

step1 with 300
step2 with 500
step3 with 700
run: 1504.652099609375ms

 

使用async await

function takeLongTime(n){
  return new Promise(resolve=>{
    setTimeout(()=>resolve(n+200),n)
  })
}

function step1(n){
  console.log(`step1 with ${n}`)
  return takeLongTime(n);
}

function step2(n){
  console.log(`step2 with ${n}`)
  return takeLongTime(n);
}

function step3(n){
  console.log(`step3 with ${n}`)
  return takeLongTime(n);
}


async function run(){
  console.time('run')
  const time1=300
  const time2=await step1(time1)
  const time3=await step1(time2)
  const result=await step1(time3)
  console.log(`result is ${result}`)
  console.timeEnd('run')
}

run()

結果和以前的 Promise 實現是同樣的,可是這個代碼看起來是否是清晰得多,幾乎跟同步代碼同樣

 

await 命令後面的 Promise 對象,運行結果多是 rejected,因此最好把 await 命令放在 try...catch 代碼塊中

async function myFunction() {
  try {
    await somethingThatReturnsAPromise();
  } catch (err) {
    console.log(err);
  }
}

// 另外一種寫法

async function myFunction() {
  await somethingThatReturnsAPromise().catch(function (err){
    console.log(err);
  });
}

 

async function dbFuc(db) {
  let docs = [{}, {}, {}];

  // 報錯
  docs.forEach(function (doc) {
    await db.post(doc);
  });
}

 

await 關鍵字,await是等待的意思,那麼它等待什麼呢,它後面跟着什麼呢?其實它後面能夠聽任何表達式,不過咱們更多的是放一個返回promise 對象的表達式。注意await 關鍵字只能放到async 函數裏面

如今寫一個函數,讓它返回promise 對象,該函數的做用是2s 以後讓數值乘以2

複製代碼
// 2s 以後返回雙倍的值
function doubleAfter2seconds(num) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(2 * num)
        }, 2000);
    } )
}
複製代碼

  如今再寫一個async 函數,從而可使用await 關鍵字, await 後面放置的就是返回promise對象的一個表達式,因此它後面能夠寫上 doubleAfter2seconds 函數的調用

async function testResult() {
    let result = await doubleAfter2seconds(30);
    console.log(result);
}

  如今調用testResult 函數

testResult();

  打開控制檯,2s 以後,輸出了60. 

  如今咱們看看代碼的執行過程,調用testResult 函數,它裏面遇到了await, await 表示等一下,代碼就暫停到這裏,再也不向下執行了,它等什麼呢?等後面的promise對象執行完畢,而後拿到promise resolve 的值並進行返回,返回值拿到以後,它繼續向下執行。具體到 咱們的代碼, 遇到await 以後,代碼就暫停執行了, 等待doubleAfter2seconds(30) 執行完畢,doubleAfter2seconds(30) 返回的promise 開始執行,2秒 以後,promise resolve 了, 並返回了值爲60, 這時await 纔拿到返回值60, 而後賦值給result, 暫停結束,代碼纔開始繼續執行,執行 console.log語句。

  就這一個函數,咱們可能看不出async/await 的做用,若是咱們要計算3個數的值,而後把獲得的值進行輸出呢?

複製代碼
async function testResult() {
    let first = await doubleAfter2seconds(30);
    let second = await doubleAfter2seconds(50);
    let third = await doubleAfter2seconds(30);
    console.log(first + second + third);
}
複製代碼

  6秒後,控制檯輸出220, 咱們能夠看到,寫異步代碼就像寫同步代碼同樣了,再也沒有回調地域了。

 

補充:在vue中使用

設計使用場景,一個手機充值活動,實現選擇用戶的省市,點擊充值按鈕,彈出相應省份的充值列表,2個請求。

請求1 獲取所在省市:            根據手機號獲得省和市            方法命名爲getLocation    接受一個參數phoneNum             返回結果 province 和city

請求2 獲取可充值面值列表:根據省和市獲得充值面值列表   方法命名爲getFaceList     接受兩個參數province 和city     返回充值列表 

咱們首先要根據手機號獲得省和市,因此寫一個方法來發送請求獲取省和市,方法命名爲getLocation, 接受一個參數phoneNum ,當獲取到城市位置之後,咱們再發送請求獲取充值面值,因此還要再寫一個方法getFaceList, 它接受兩個參數, province 和city, 

  methods: {
      //獲取到城市信息
      getLocation(phoneNum) {
          return axios.post('phoneLocation', {phoneNum:phoneNum})
      },
      // 獲取面值
      getFaceList(province, city) {
          return axios.post('/faceList', {province:province,city:city})
      },
      // 點擊肯定按鈕時,顯示面值列表
      getFaceResult () {
        this.getLocation(this.phoneNum)
          .then(res => {
            if (res.code=='ok') {
                let province = res.data.obj.province;
                let city = res.data.obj.city;
                this.getFaceList(province, city)
                    .then(res => {
                        if(res.code=='ok') {
                          //最終獲取到面值列表
                          this.faceList = res.data.obj
                        }
                    })
            }
      })
      .catch(err => {
          console.log(err)
      })          
    }
  }

如今點擊肯定按鈕,能夠看到頁面中輸出了 從後臺返回的面值列表。這時你看到了then 的鏈式寫法,有一點回調地域的感受。如今咱們在有async/ await 來改造一下。

首先把 getFaceResult 轉化成一個async 函數,就是在其前面加async, 由於它的調用方法和普通函數的調用方法是一致,因此沒有什麼問題。而後就把 getLocation 和

getFaceList 放到await 後面,等待執行, getFaceResult  函數修改以下
  methods: {
      //獲取到城市信息
      getLocation(phoneNum) {
          return axios.post('phoneLocation', {phoneNum:phoneNum})
      },
      // 獲取面值
      getFaceList(province, city) {
          return axios.post('/faceList', {province:province,city:city})
      },
      // 點擊肯定按鈕時,顯示面值列表
      async getFaceResult () {
        let location = await this.getLocation(this.phoneNum);
        if (location.code=='ok') {
            let province = location.data.obj.province;
            let city = location.data.obj.city;
            let result = await this.getFaceList(province, city);
            if (result.code=='ok') {
                this.faceList = result.data.obj;
            }
        }        
      }
  }

如今代碼的書寫方式,就像寫同步代碼同樣,沒有回調的感受,很是舒服。

如今就還差一點須要說明,那就是怎麼處理異常,若是請求發生異常,怎麼處理? 它用的是try/catch 來捕獲異常,把await 放到 try 中進行執行,若有異常,就使用catch 進行處理。

  methods: {
      //獲取到城市信息
      getLocation(phoneNum) {
          return axios.post('phoneLocation', {phoneNum:phoneNum})
      },
      // 獲取面值
      getFaceList(province, city) {
          return axios.post('/faceList', {province:province,city:city})
      },
      // 點擊肯定按鈕時,顯示面值列表
      async getFaceResult () {
          try {
              let location = await this.getLocation(this.phoneNum);
              if (location.code=='ok') {
                  let province = location.data.obj.province;
                  let city = location.data.obj.city;
                  let result = await this.getFaceList(province, city);
                  if (result.code=='ok') {
                      this.faceList = result.data.obj;
                  }
              }
          } catch(err) {
              console.log(err);
          }
      }
  }

 

 

 

 

參考:https://www.cnblogs.com/SamWeb/p/8417940.html

 

異步解決方案 async和await

前言

異步編程模式在前端開發過程當中,顯得愈來愈重要。從最開始的XHR到封裝後的Ajax都在試圖解決異步編程過程當中的問題。隨着ES6新標準的到來,處理異步數據流又有了新的方案。咱們都知道,在傳統的ajax請求中,當異步請求之間的數據存在依賴關係的時候,就可能產生很難看的多層回調,俗稱'回調地獄'(callback hell),這卻讓人望而生畏,Promise的出現讓咱們告別回調函數,寫出更優雅的異步代碼。在實踐過程當中,卻發現Promise並不完美,Async/Await是近年來JavaScript添加的最革命性的的特性之一,Async/Await提供了一種使得異步代碼看起來像同步代碼的替代方法。接下來咱們介紹這兩種處理異步編程的方案。

1、Promise的原理與基本語法

1.Promise的原理

Promise 是一種對異步操做的封裝,能夠經過獨立的接口添加在異步操做執行成功、失敗時執行的方法。主流的規範是 Promises/A+。

Promise中有幾個狀態:

  • pending: 初始狀態, 非 fulfilled 或 rejected;

  • fulfilled: 成功的操做,爲表述方便,fulfilled 使用 resolved 代替;

  • rejected: 失敗的操做。


pending能夠轉化爲fulfilled或rejected而且只能轉化一次,也就是說若是pending轉化到fulfilled狀態,那麼就不能再轉化到rejected。而且fulfilled和rejected狀態只能由pending轉化而來,二者之間不能互相轉換。

2.Promise的基本語法

  • Promise實例必須實現then這個方法

  • then()必須能夠接收兩個函數做爲參數

  • then()返回的必須是一個Promise實例

<script src="https://cdn.bootcss.com/bluebird/3.5.1/bluebird.min.js"></script>//若是低版本瀏覽器不支持Promise,經過cdn這種方式
      <script type="text/javascript">
        function loadImg(src) {
            var promise = new Promise(function (resolve, reject) {
                var img = document.createElement('img')
                img.onload = function () {
                    resolve(img)
                }
                img.onerror = function () {
                    reject('圖片加載失敗')
                }
                img.src = src
            })
            return promise
        }
        var src = 'https://www.imooc.com/static/img/index/logo_new.png'
        var result = loadImg(src)
        result.then(function (img) {
            console.log(1, img.width)
            return img
        }, function () {
            console.log('error 1')
        }).then(function (img) {
            console.log(2, img.height)
        })
     </script>

2、Promise多個串聯操做

Promise還能夠作更多的事情,好比,有若干個異步任務,須要先作任務1,若是成功後再作任務2,任何任務失敗則再也不繼續並執行錯誤處理函數。要串行執行這樣的異步任務,不用Promise須要寫一層一層的嵌套代碼。

有了Promise,咱們只須要簡單地寫job1.then(job2).then(job3).catch(handleError);
其中job一、job2和job3都是Promise對象。

好比咱們想實現第一個圖片加載完成後,再加載第二個圖片,若是其中有一個執行失敗,就執行錯誤函數:

var src1 = 'https://www.imooc.com/static/img/index/logo_new.png'
        var result1 = loadImg(src1) //result1是Promise對象
        var src2 = 'https://img1.mukewang.com/545862fe00017c2602200220-100-100.jpg'
        var result2 = loadImg(src2) //result2是Promise對象
        result1.then(function (img1) {
            console.log('第一個圖片加載完成', img1.width)
            return result2  // 鏈式操做
        }).then(function (img2) {
            console.log('第二個圖片加載完成', img2.width)
        }).catch(function (ex) {
            console.log(ex)
        })

這裏需注意的是:then 方法能夠被同一個 promise 調用屢次,then 方法必須返回一個 promise 對象。上例中result1.then若是沒有明文返回Promise實例,就默認爲自己Promise實例即result1,result1.then返回了result2實例,後面再執行.then實際上執行的是result2.then

3、Promise經常使用方法

除了串行執行若干異步任務外,Promise還能夠並行執行異步任務。

試想一個頁面聊天系統,咱們須要從兩個不一樣的URL分別得到用戶的我的信息和好友列表,這兩個任務是能夠並行執行的,用Promise.all()實現以下:

var p1 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 500, 'P1');
});
var p2 = new Promise(function (resolve, reject) {
    setTimeout(resolve, 600, 'P2');
});
// 同時執行p1和p2,並在它們都完成後執行then:
Promise.all([p1, p2]).then(function (results) {
    console.log(results); // 得到一個Array: ['P1', 'P2']
});

有些時候,多個異步任務是爲了容錯。好比,同時向兩個URL讀取用戶的我的信息,只須要得到先返回的結果便可。這種狀況下,用Promise.race()實現:

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執行較快,Promise的then()將得到結果'P1'。p2仍在繼續執行,但執行結果將被丟棄。

總結:Promise.all接受一個promise對象的數組,待所有完成以後,統一執行success;

Promise.race接受一個包含多個promise對象的數組,只要有一個完成,就執行success

接下來咱們對上面的例子作下修改,加深對這二者的理解:

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])//<img src="https://www.imooc.com/static/img/index/logo_new.png">
         console.log('all', datas[1])//<img src="https://img1.mukewang.com/545862fe00017c2602200220-100-100.jpg">
     })
     Promise.race([result1, result2]).then(function (data) {
         console.log('race', data)//<img src="https://img1.mukewang.com/545862fe00017c2602200220-100-100.jpg">
     })

若是咱們組合使用Promise,就能夠把不少異步任務以並行和串行的方式組合起來執行

4、Async/Await簡介與用法

異步操做是 JavaScript 編程的麻煩事,不少人認爲async函數是異步操做的終極解決方案。

一、Async/Await簡介

  • async/await是寫異步代碼的新方式,優於回調函數和Promise。

  • async/await是基於Promise實現的,它不能用於普通的回調函數。

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

  • async/await使得異步代碼看起來像同步代碼,再也沒有回調函數。可是改變不了JS單線程、異步的本質。

二、Async/Await的用法

  • 使用await,函數必須用async標識

  • await後面跟的是一個Promise實例

  • 須要安裝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()

當函數執行的時候,一旦遇到 await 就會先返回,等到觸發的異步操做完成,再接着執行函數體內後面的語句。

5、Async/Await錯誤處理

await 命令後面的 Promise 對象,運行結果多是 rejected,因此最好把 await 命令放在 try...catch 代碼塊中。try..catch錯誤處理也比較符合咱們日常編寫同步代碼時候處理的邏輯。

async function myFunction() {
  try {
    await somethingThatReturnsAPromise();
  } catch (err) {
    console.log(err);
  }
}

6、爲何Async/Await更好?

Async/Await較Promise有諸多好處,如下介紹其中三種優點:

1. 簡潔

使用Async/Await明顯節約了很多代碼。咱們不須要寫.then,不須要寫匿名函數處理Promise的resolve值,也不須要定義多餘的data變量,還避免了嵌套代碼。

2. 中間值

你極可能遇到過這樣的場景,調用promise1,使用promise1返回的結果去調用promise2,而後使用二者的結果去調用promise3。你的代碼極可能是這樣的:

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

使用async/await的話,代碼會變得異常簡單和直觀

const makeRequest = async () => {
  const value1 = await promise1()
  const value2 = await promise2(value1)
  return promise3(value1, value2)
}

3.條件語句

下面示例中,須要獲取數據,而後根據返回數據決定是直接返回,仍是繼續獲取更多的數據。

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層)可讀性較差,它們傳達的意思只是須要將最終結果傳遞到最外層的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    
  }
}

參考文章

Async/Await替代Promise的6個理由

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

廖雪峯的Javascript教程

[譯] Promises/A+ 規範

async 函數的含義和用法

相關文章
相關標籤/搜索