<font id="zqva1"></font>
<rt id="zqva1"></rt>
  • <tt id="zqva1"></tt>
    <cite id="zqva1"></cite>

    <cite id="zqva1"><noscript id="zqva1"></noscript></cite>
      <rp id="zqva1"><meter id="zqva1"></meter></rp>

        <cite id="zqva1"></cite>
          <b id="zqva1"></b>
          <rp id="zqva1"></rp>
          <cite id="zqva1"></cite>

          <rt id="zqva1"></rt>

        1. <rp id="zqva1"></rp>

          Async/Await替代Promise的6個理由

          時間:?2017-12-13閱讀:?861標簽:?Promise

          Node.js 7.6已經支持async/await了,如果你還沒有試過,這篇文章將告訴你為什么要用它。


          Async/Await簡介

          對于從未聽說過async/await的朋友,下面是簡介:

          async/await是寫異步代碼的新方式,以前的方法有回調函數和Promise。

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

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

          async/await使得異步代碼看起來像同步代碼,這正是它的魔力所在。


          Async/Await語法

          示例中,getJSON函數返回一個promise,這個promise成功resolve時會返回一個json對象。我們只是調用這個函數,打印返回的JSON對象,然后返回”done”。

          使用Promise是這樣的:

          const makeRequest = () =>getJSON().then(data => {
              console.log(data)
              return "done"
          })
          makeRequest()


          使用Async/Await是這樣的:

          const makeRequest = async () => {
              console.log(await getJSON())
              return "done"
          }
          makeRequest()

          它們有一些細微不同:

          函數前面多了一個aync關鍵字。await關鍵字只能用在aync定義的函數內。async函數會隱式地返回一個promise,該promise的reosolve值就是函數return的值。(示例中reosolve值就是字符串”done”)

          第1點暗示我們不能在最外層代碼中使用await,因為不在async函數內。

          // 不能在最外層代碼中使用
          awaitawait makeRequest()
          // 這是會出事情的 
          makeRequest().then((result) => {
              // 代碼
          })

          await getJSON()表示console.log會等到getJSON的promise成功reosolve之后再執行。


          為什么Async/Await更好?


          1. 簡潔

          由示例可知,使用Async/Await明顯節約了不少代碼。我們不需要寫.then,不需要寫匿名函數處理Promise的resolve值,也不需要定義多余的data變量,還避免了嵌套代碼。這些小的優點會迅速累計起來,這在之后的代碼示例中會更加明顯。

          const Promise = require("bluebird")
          var readFile = Promise.promisify(require("fs").readFile)
          
          // 使用Promise
          function usePromise()
          {
              let a
              readFile("a.txt", "utf8")
                  .then(tmp =>
                  {
                      a = tmp
                      return readFile("b.txt", "utf8")
                  })
                  .then(b =>
                  {
                      let result = a + b
                      console.log(result) // 輸出"Hello, Fundebug!"
                  })
          }
          
          // 使用Async/Await
          async function useAsyncAwait()
          {
              let a = await readFile("a.txt", "utf8")
              let b = await readFile("b.txt", "utf8")
              let result = a + b
              console.log(result) // 輸出"Hello, Fundebug!"
          }
          
          usePromise()
          useAsyncAwait()

          由示例可知,使用Async/Await極大地簡化了代碼,使得代碼可讀性提高了非常多。 

           

          2. 錯誤處理

          Async/Await讓try/catch可以同時處理同步和異步錯誤。在下面的promise示例中,try/catch不能處理JSON.parse的錯誤,因為它在Promise中。我們需要使用.catch,這樣錯誤處理代碼非常冗余。并且,在我們的實際生產代碼會更加復雜。

          const makeRequest = () => {
              try {getJSON().then(result => {
                  // JSON.parse可能會出錯
                  const data = JSON.parse(result)
                  console.log(data)})
                  // 取消注釋,處理異步代碼的錯誤
                  // .catch((err) => {
                  //  console.log(err)
                  // })
              } catch (err) {
                  console.log(err)
              }
          }

          使用aync/await的話,catch能處理JSON.parse錯誤:

          const makeRequest = async () => {
              try {
                  // this parse may fail
                  const data = JSON.parse(await getJSON())
                  console.log(data)} 
              catch (err) {
                  console.log(err)
              }
          }


          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層),括號,return語句很容易讓人感到迷茫,而它們只是需要將最終結果傳遞到最外層的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
              }
          }


          4. 中間值

          你很可能遇到過這樣的場景,調用promise1,使用promise1返回的結果去調用promise2,然后使用兩者的結果去調用promise3。你的代碼很可能是這樣的:

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

          如果promise3不需要value1,可以很簡單地將promise嵌套鋪平。如果你忍受不了嵌套,你可以將value 1 & 2 放進Promise.all來避免深層嵌套:

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

          這種方法為了可讀性犧牲了語義。除了避免嵌套,并沒有其他理由將value1和value2放在一個數組中。

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

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


          5. 錯誤棧

          下面示例中調用了多個Promise,假設Promise鏈中某個地方拋出了一個錯誤:

          const makeRequest = () => {
              return callAPromise()
                  .then(() => callAPromise())
                  .then(() => callAPromise())
                  .then(() => callAPromise())
                  .then(() => callAPromise())
                  .then(() => {throw new Error("oops");}
              )}
          makeRequest().catch(err => {
              console.log(err);
              // output
              // Error: oops at callAPromise.then.then.then.then.then (index.js:8:13)
          })

          Promise鏈中返回的錯誤棧沒有給出錯誤發生位置的線索。更糟糕的是,它會誤導我們;錯誤棧中唯一的函數名為callAPromise,然而它和錯誤沒有關系。(文件名和行號還是有用的)。

          然而,async/await中的錯誤棧會指向錯誤所在的函數:

          const makeRequest = async () => {
              await callAPromise()
              await callAPromise()
              await callAPromise()
              await callAPromise()
              await callAPromise()
              throw new Error("oops");
          }
          
          makeRequest().catch(err => {
              console.log(err);
              // output
              // Error: oops at makeRequest (index.js:7:9)
          })

          在開發環境中,這一點優勢并不大。但是,當你分析生產環境的錯誤日志時,它將非常有用。這時,知道錯誤發生在makeRequest比知道錯誤發生在then鏈中要好。


          結論

          Async/Await是近年來JavaScript添加的最革命性的的特性之一。它會讓你發現Promise的語法有多糟糕,而且提供了一個直觀的替代方法。

          原文: 6 Reasons Why JavaScript’s Async/Await Blows Promises Away
          譯者: Fundebug
          站長推薦

          1.阿里云: 本站目前使用的是阿里云主機,安全/可靠/穩定。點擊領取2000元代金券、了解最新阿里云產品的各種優惠活動點擊進入

          2.騰訊云: 提供云服務器、云數據庫、云存儲、視頻與CDN、域名等服務。騰訊云各類產品的最新活動,優惠券領取點擊進入

          3.廣告聯盟: 整理了目前主流的廣告聯盟平臺,如果你有流量,可以作為參考選擇適合你的平臺點擊進入

          鏈接: http://www.modern-decoration.com.cn/article/detial/246

          promise

          Promise的構造函數接收一個參數,是函數,并且傳入兩個參數:resolve,reject,分別表示異步操作執行成功后的回調函數和異步操作執行失敗后的回調函數

          你真的懂Promise嗎

          在異步編程中,Promise 扮演了舉足輕重的角色,比傳統的解決方案(回調函數和事件)更合理和更強大。可能有些小伙伴會有這樣的疑問:2020年了,怎么還在談論Promise?

          動手寫一個Promise

          現在Promise用的比較頻繁了,如果哪天突然不用了,可能邏輯就不好厘清了,回調沒的說是一大把,Promise這個東西很神奇,用起來舒服,若自己寫一下,恐怕還真不簡單,關鍵就一個字“繞”,繞過了也就好了

          Promise.then鏈式調用順序

          想用Promise異步實現一個遞歸調用的接口,用來做簡單AI的動作序列。發現一開始接觸這個then的時候,不是很清楚,參考了網上的一些寫法,改成自己的有問題,所以先靜下心來研究一下這個調用的順序問題

          這 10 個片段,有助于你理解 ES 中的 Promise

          在開發中,了解 JavaScript 和 Promise 基礎,有助于提高我們的編碼技能,今天,我們一起來看看下面的 10 片段,相信看完這 10 個片段有助于我們對 Promise 的理解。

          這幾個Promise的輸出到底是?

          我們使用構造函數方法創建一個Promise實例,立即使用 reject 回調觸發一個錯誤。catch處理程序的工作方式類似于DOM的 .addeventlistener(事件、回調)或事件發射器的 .on(事件、回調),其中可以添加多個回調。每個回調都具有相同的參數。

          ES6之Promise

          所謂的 promise,簡單的來說就是一個容器,里面保存著某個未來才會結束的事件(也就是我們的異步操作)的結果。從語法上面來說,Promise 是一個對象,從它可以獲取異步操作的消息。Promise 提供統一的 API,各種異步操作都可以用同樣的方法進行處理。

          Promise 中的三兄弟 .all(), .race(), .allSettled()

          從ES6 開始,我們大都使用的是 Promise.all()和Promise.race(),Promise.allSettled() 提案已經到第4階段,因此將會成為ECMAScript 2020的一部分。Promise.all<T>(promises: Iterable<Promise<T>>): Promise<Array<T>>

          Promise入門詳解和基本用法

          所謂單線程,是指JS引擎中負責解釋和執行JavaScript代碼的線程只有一個,也就是一次只能完成一項任務,這個任務執行完后才能執行下一個,它會「阻塞」其他任務。這個任務可稱為主線程。異步模式可以一起執行多個任務。

          從 callback 到 promise

          說起回調(callback),那可以說是 JS 最基礎的異步調用方式,是 JS 為解決阻塞請求而量身定制出的一種設計模式,在 JS 或是說前端大潮中有著舉足輕重的影響

          內容以共享、參考、研究為目的,不存在任何商業目的。其版權屬原作者所有,如有侵權或違規,請與小編聯系!情況屬實本人將予以刪除!

          文章投稿關于web前端網站點搜索站長推薦網站地圖站長QQ:522607023

          小程序專欄: 土味情話心理測試腦筋急轉彎幽默笑話段子句子語錄成語大全運營推廣

          国产精品高清视频免费 - 视频 - 在线观看 - 影视资讯 - 唯爱网