亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

async屬不屬于es6屬性

發布時間:2022-10-24 17:08:21 來源:億速云 閱讀:123 作者:iii 欄目:web開發

本篇內容介紹了“async屬不屬于es6屬性”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

屬于,async是es6的新特性,用于表明程序里面可能有異步過程。用async關鍵字聲明的函數返回的是一個Promise對象,如果在函數中return一個直接量,async會把這個直接量通過Promise.resolve()封裝成Promise對象;當async函數沒有返回值時,返回“Promise.resolve(undefined)”。

ES6新特性 async和await關鍵字

1、初步了解

我們先從字面意思來理解這兩個關鍵字,async是asynchronous(異步)的簡寫,而await可以認為是async wait的簡寫。所以async可以理解為用于聲明一個函數是異步的,而await用于等待一個異步任務執行完成。

async和await關鍵字讓我們可以用一種更簡潔的方式寫出基于promise的異步行為,而無需刻意地鏈式調用promise。

接下來我們通過先幾個例子,初步了解一下async和await的作用。

知識點1: 用 async 關鍵字聲明的函數返回的是一個 Promise 對象。如果在函數中 return 一個直接量,async 會把這個直接量通過 Promise.resolve() 封裝成 Promise 對象。當 async 函數沒有返回值時,返回 Promise.resolve(undefined)

 //定義一個普通函數,返回一個字符串
 function test() {
     return "hello async";
 }
 const result1 = test();
 console.log(result1); //輸出一個字符串 hello async
 
 //定義一個使用了async修飾的函數,同樣返回一個字符串
 async function testAsync() {
     return "hello async";
 }
 const result2 = testAsync();
 console.log(result2); //輸出一個Promise對象 Promise {<fulfilled>: 'hello async'}
 //async較好的用法
 async function testAsync(){
     //返回一個Promise對象
     return new Promise((resolve, reject)=>{
         //處理異步任務
         setTimeout(function () {
             resolve("testAsync")
         }, 1000);
     })
 }
 //async通常用于聲明一個處理異步任務且返回了Promise對象的函數

知識點2: await關鍵字只能使用在被async聲明的函數內,用于修飾一個Promise對象,使得該Promise對象處理的異步任務在當前協程上按順序同步執行。

 //定義一個使用async修飾的函數,處理異步任務
 async function testAsync(){
     return new Promise((resolve, reject)=>{
         setTimeout(function () {
             resolve("testAsync")
         }, 1000);
     })
 }
 //定義一個函數,直接調用testAsync函數
 function testAwait(){
     console.log('testAsync調用前')
     testAsync().then(res=>{
         console.log(res) //輸出"testAsync"
     })
     console.log('testAsync調用后')
 }
 
 /***** 輸出如下 *****/
 testAsync調用前
 testAsync調用后
 testAsync
 //盡管代碼按順序寫,但不按順序執行,因為testAsync()是異步函數
 //定義一個函數(不使用async聲明該函數)用await修飾調用testAsync函數
 function testAwait(){
     console.log('testAsync調用前')
     await testAsync().then(res=>{ //使用await關鍵字修飾
         console.log(res)
     })
     console.log('testAsync調用后')
 }
 
 //調用testAwait()函數
 testAwait()
 //報錯:Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules,因為await只能使用在被async修飾的函數內。
 //定義一個函數(使用async聲明該函數)用await修飾調用testAsync函數
 async function testAwait(){
     console.log('testAsync調用前')
     await testAsync().then(res=>{
         console.log(res)
     })
     console.log('testAsync調用后')
 }
 
 /***** 輸出如下 *****/
 testAsync調用前
 testAsync
 testAsync調用后
 
 //使用了await關鍵字修飾,使得代碼按照順序執行,即同步執行

2、async關鍵字

(1)用于表明程序里面可能有異步過程

(2)async函數返回值的類型為Promise對象: 這是和普通函數本質上不同的地方,也是使用時重點注意的地方;

  • return newPromise( ),這個用法符合async函數本意;

  • return data,特別注意到是這樣子寫相當于Promise.resolve(data),返回的data被封裝成一個Promise對象,但是在調用async函數的地方通過簡單的=是拿不到這個返回值data的,因為返回值是一個Promise對象,所以需要用.then(data => { })方式才可以拿到這個data;

  • 如果沒有返回值,相當于返回了Promise.resolve(undefined);

(3)無等待,非阻塞:使用async關鍵字聲明的函數里面如果有異步過程可能會等待,但是函數本身會馬上返回,不會阻塞當前主線程。如果在函數里面使用了await關鍵字修飾的異步過程,其工作在相應的協程上,會阻塞等待異步任務的完成再返回。

 //定義一個函數,處理異步任務(使用定時器模擬),返回一個Promise對象
 async function testAsync(){
     return new Promise((resolve, reject) => {
       setTimeout(function () {
         resolve("成功調用testAsync")
       }, 1000);
     });
 }
 
 //定義一個函數,使用await關鍵字修飾調用testAsync()函數
 async function testAwait(){
     //使用了await關鍵字修飾調用testAsyn()函數
     await this.testAsync().then(res=>{
       console.log(res) //輸出的是testAsync()函數resolve的值
     });
     console.log("helloAsync");
 }
 
 //主線程
 console.log('testAwait調用前')
 testAwait();
 console.log('testAwait調用后')
 
 /***** 輸出結果如下 *****/
 testAwait調用前
 testAwait調用后 //因為testAwait()函數使用了async關鍵字修飾,所以不會阻塞主線程的執行,所以這兩句話會先直接輸出,然后再執行testAwait()函數
 成功調用testAsync //因為testAwait()函數在內部調用testAsync()函數時使用了await關鍵字修飾,所以在對應的協程上會阻塞,等待testAsync()函數執行完,再輸出下面那句'helloAsync'
 helloAsync

3、await關鍵字

(1)await只能在async函數內部使用:不能放在普通函數里面,否則會報錯。

(2)await關鍵字后面跟的是一個Promise對象。如果跟的是一個函數,則這個函數應當返回一個Promise對象。如果跟的是非Promise對象,則會通過Promise.resolve( )函數自動將這個東西包裝成一個Promise對象并置于fulfilled狀態。

 //例如:
 const a = await 'Hello Await'
 // 相當于
 const a = await Promise.resolve('Hello Await');
 
 console.log(a) //輸出 'Hello Await'

(3)await的本質是等待它所修飾的Promise對象的fulfilled狀態,并把resolve(data)的數據data返回。

意思是,如果await后面跟的是一個 Promise 對象,await 就會阻塞后面的代碼,等著 Promise 對象 resolve,然后得到 resolve 的值,作為 await 表達式的運算結果。

 async function testAsync(){
     return new Promise((resolve, reject) => {
       setTimeout(function () {
         resolve("成功調用testAsync")
       }, 1000);
     });
 }
 
 const a = await testAsync() //這里的a就會拿到testAsync函數resolve的數據
 console.log(a) //在一秒后輸出'成功調用testAsync'

(4)await并不關心它所修飾的Promise對象的rejected狀態,即reject(data)的數據data并不會被await處理,所以建議通過Promise對象調用catch去捕獲。

 async testAwait(){
     //變量a用于接收testAsync()函數resolve的數據
     let a = await testAsync().catch(err=>{
         //處理異常和reject的數據
     })    
 }

4、深入講解async和await

(1)執行順序

 //定義一個函數,該函數接收一個參數,1s后再返回參數的兩倍
 async function double(num) {
     return new Promise((resolve, reject) => {
         setTimeout(() => { //使用定時器模擬異步任務
             resolve(2 * num) //將運算結果交給resolve
         }, 1000);
     })
 }
 
 async function getResult () {
     console.log('double調用前')  //順序:2
     let result = await double(10); //將10作為參數傳遞給double函數
     //result變量用于接收double()函數resolve的值
     console.log(result); //順序:4
     console.log('double調用后') //順序:4
 }
 
 console.log('getResult調用前') //順序:1
 getResult();
 console.log('getResult調用后') //順序:3
 
 /***** 依次輸出如下 *****/
 getResult調用前
 double調用前
 getResult調用后
 20 //1s后輸出
 double調用后

①首先打印輸出getResult調用前,同步代碼,順序執行;

②然后調用方法getResult( ),打印輸出double調用前,同步代碼,順序執行;

③再調用異步方法double( )

如果此處沒有使用await關鍵字修飾,則依次輸出的是:getResult調用前、double調用前、double調用后、getResult調用后、1s后輸出20

因為異步操作不會影響其他代碼的執行,所以會將其他代碼按順序執行完,最后再執行double函數

因為這里使用了await關鍵字,所以getResult( )的代碼執行到這里就會被阻塞,等到double函數resolve了,再往下執行

④盡管getResult函數內部被await阻塞了,由于getResult函數本身也是個async函數,所以它不會影響getResult函數外面的代碼執行。因為調用async函數不會造成阻塞,它內部的所有阻塞都被封裝在一個Promise對象中異步執行。

⑤所以在調用getResult函數后,會繼續向下執行,即打印輸出getResult調用后

⑥當1s之后,異步函數double執行完成,將結果交給resolve。

⑦通過await關鍵字接收到double函數resolve的值,賦值給result變量。打印輸出20

⑧因為使用了await阻塞將異步變為同步,所以在打印輸出20后再打印輸出double調用后

(2)處理reject回調

 //方法一:通過promise對象的catch進行捕獲
 function a(){
     return new Promise((resolve,reject) => {
         setTimeout(() => {
             reject("something")
         }, 1000)
     })
 }
 
 async function b(){
     let r = await a().catch((err)=>{
         console.log(err)
     })
 }
 //方法二:通過try/catch語句處理
 function a(){
     return new Promise((resolve,reject) => {
         setTimeout(() => {
             reject("something")
         }, 1000)
     })
 }
 
 async function b(){
     let r = null
     try{
        r = await a()
     }catch(err){
         console.log(err)
     }
 }

(3)使用await優化Promise對象的回調地獄問題

在Promise章節中我們通過了Promise對象的then( )方法鏈式調用解決了回調地獄問題,但看起來仍然不夠美觀,我們可以通過await優化一下,讓它看起來更符合我們平時代碼的編寫習慣。

 //原本的解決方案
 //第二個請求依賴于第一個請求的返回值,第三個請求依賴于第二個請求的返回值
 request1().then(function(data){ 
     return request2(data)
 }).then(function(data){ 
     return request3(data)
 })
 //這里只發送了三次請求,代碼看起來還不錯,雖然它已經比普通的回調函數形式好了很多。
 //那如果需要發送五次或十次請求呢?代碼也許會沒那么美觀,接下來我們使用學習到的await去解決這個問題。

原本的要求是每個請求都依賴于上一個請求的返回值,那么是不是得等一個請求完,才能發送下一個請求?這時我們可以思考一下,await的作用是什么?是不是對一個Promise對象去進行阻塞,使其狀態變為fulfilled后獲取resolve的值。這不就正是我們所需要的。

 //使用await的解決方案
 var res1 = await request1() //將request1的返回值賦值給res1
 var res2 = await request2(res1) //將res1作為參數傳給request2,并將request2的返回值賦值給res2
 var res3 = await request3(res2) //同理
 
 //這樣子寫的代碼更加的美觀,并且更符合我們平時編寫代碼的習慣

“async屬不屬于es6屬性”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

湖北省| 罗源县| 延津县| 新昌县| 时尚| 潜江市| 正阳县| 漠河县| 河池市| 蓬安县| 台北县| 阳曲县| 额济纳旗| 扎赉特旗| 白沙| 财经| 板桥市| 吴川市| 虹口区| 丰原市| 广宁县| 五大连池市| 仪陇县| 裕民县| 茶陵县| 孟村| 惠州市| 清水县| 辽阳市| 兴仁县| 宁夏| 龙游县| 景德镇市| 青神县| 康马县| 阜康市| 固原市| 会东县| 郁南县| 长宁区| 永和县|