目錄
ES6新特性async和await關鍵字
#1、初步了解
2、async關鍵字
3、await關鍵字
4、深入解說async和await
首頁 web前端 前端問答 async屬於es6屬性嗎

async屬於es6屬性嗎

Oct 20, 2022 pm 03:01 PM
javascript es6

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

async屬於es6屬性嗎

本教學操作環境:windows7系統、ECMAScript 6版、Dell G3電腦。

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) //同理
 
 //这样子写的代码更加的美观,并且更符合我们平时编写代码的习惯
登入後複製

【相关推荐:javascript视频教程编程视频

以上是async屬於es6屬性嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用WebSocket和JavaScript實現線上語音辨識系統 如何使用WebSocket和JavaScript實現線上語音辨識系統 Dec 17, 2023 pm 02:54 PM

如何使用WebSocket和JavaScript實現線上語音辨識系統引言:隨著科技的不斷發展,語音辨識技術已成為了人工智慧領域的重要組成部分。而基於WebSocket和JavaScript實現的線上語音辨識系統,具備了低延遲、即時性和跨平台的特點,成為了廣泛應用的解決方案。本文將介紹如何使用WebSocket和JavaScript來實現線上語音辨識系

WebSocket與JavaScript:實現即時監控系統的關鍵技術 WebSocket與JavaScript:實現即時監控系統的關鍵技術 Dec 17, 2023 pm 05:30 PM

WebSocket與JavaScript:實現即時監控系統的關鍵技術引言:隨著互聯網技術的快速發展,即時監控系統在各個領域中得到了廣泛的應用。而實現即時監控的關鍵技術之一就是WebSocket與JavaScript的結合使用。本文將介紹WebSocket與JavaScript在即時監控系統中的應用,並給出程式碼範例,詳細解釋其實作原理。一、WebSocket技

如何利用JavaScript和WebSocket實現即時線上點餐系統 如何利用JavaScript和WebSocket實現即時線上點餐系統 Dec 17, 2023 pm 12:09 PM

如何利用JavaScript和WebSocket實現即時線上點餐系統介紹:隨著網路的普及和技術的進步,越來越多的餐廳開始提供線上點餐服務。為了實現即時線上點餐系統,我們可以利用JavaScript和WebSocket技術。 WebSocket是一種基於TCP協定的全雙工通訊協議,可實現客戶端與伺服器的即時雙向通訊。在即時線上點餐系統中,當使用者選擇菜餚並下訂單

如何使用WebSocket和JavaScript實現線上預約系統 如何使用WebSocket和JavaScript實現線上預約系統 Dec 17, 2023 am 09:39 AM

如何使用WebSocket和JavaScript實現線上預約系統在當今數位化的時代,越來越多的業務和服務都需要提供線上預約功能。而實現一個高效、即時的線上預約系統是至關重要的。本文將介紹如何使用WebSocket和JavaScript來實作一個線上預約系統,並提供具體的程式碼範例。一、什麼是WebSocketWebSocket是一種在單一TCP連線上進行全雙工

JavaScript與WebSocket:打造高效率的即時天氣預報系統 JavaScript與WebSocket:打造高效率的即時天氣預報系統 Dec 17, 2023 pm 05:13 PM

JavaScript和WebSocket:打造高效的即時天氣預報系統引言:如今,天氣預報的準確性對於日常生活以及決策制定具有重要意義。隨著技術的發展,我們可以透過即時獲取天氣數據來提供更準確可靠的天氣預報。在本文中,我們將學習如何使用JavaScript和WebSocket技術,來建立一個高效的即時天氣預報系統。本文將透過具體的程式碼範例來展示實現的過程。 We

簡易JavaScript教學:取得HTTP狀態碼的方法 簡易JavaScript教學:取得HTTP狀態碼的方法 Jan 05, 2024 pm 06:08 PM

JavaScript教學:如何取得HTTP狀態碼,需要具體程式碼範例前言:在Web開發中,經常會涉及到與伺服器進行資料互動的場景。在與伺服器進行通訊時,我們經常需要取得傳回的HTTP狀態碼來判斷操作是否成功,並根據不同的狀態碼來進行對應的處理。本篇文章將教你如何使用JavaScript來取得HTTP狀態碼,並提供一些實用的程式碼範例。使用XMLHttpRequest

javascript如何使用insertBefore javascript如何使用insertBefore Nov 24, 2023 am 11:56 AM

用法:在JavaScript中,insertBefore()方法用於在DOM樹中插入一個新的節點。這個方法需要兩個參數:要插入的新節點和參考節點(即新節點將要插入的位置的節點)。

JavaScript與WebSocket:打造高效率的即時影像處理系統 JavaScript與WebSocket:打造高效率的即時影像處理系統 Dec 17, 2023 am 08:41 AM

JavaScript是一種廣泛應用於Web開發的程式語言,而WebSocket則是一種用於即時通訊的網路協定。結合二者的強大功能,我們可以打造一個高效率的即時影像處理系統。本文將介紹如何利用JavaScript和WebSocket來實作這個系統,並提供具體的程式碼範例。首先,我們需要明確指出即時影像處理系統的需求和目標。假設我們有一個攝影機設備,可以擷取即時的影像數

See all articles