async は es6 属性ですか?

青灯夜游
青灯夜游オリジナル
2022-10-20 15:01:541825ブラウズ

に属する、async は es6 の新機能であり、プログラム内に非同期プロセスが存在する可能性があることを示すために使用されます。 async キーワードで宣言された関数は Promise オブジェクトを返します。関数で直接値が返された場合、async は Promise.resolve() を通じてその直接値を Promise オブジェクトにカプセル化します。async 関数が値を返さない場合は、その直接値を Promise オブジェクトにカプセル化します。 「Promise.resolve(unknown)」を返します。

async は es6 属性ですか?

このチュートリアルの動作環境: Windows 7 システム、ECMAScript バージョン 6、Dell G3 コンピューター。

ES6 の新機能 async と await キーワード

1. 予備知識

これを文字通りに理解しましょう 2 つのキーワード、async はasynchronous(非同期)の略で、awaitはasync waitの略と考えてください。したがって、async は関数を非同期であると宣言するために使用され、await は非同期タスクが完了するのを待つために使用されると理解できます。

async キーワードと await キーワードを使用すると、Promise を意図的に連鎖させることなく、より簡潔な方法で Promise ベースの非同期動作を作成できます。

次に、いくつかの例を通して async と await の機能を予備的に見てみましょう。

知識ポイント 1: async キーワードを使用して宣言された関数は、Promise オブジェクトを返します。関数で return を直接値に指定すると、async は Promise.resolve() を通じてその直接値を Promise オブジェクトにカプセル化します。 async 関数が値を返さない場合、Promise.resolve(unknown)

 //定义一个普通函数,返回一个字符串
 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 関数の戻り値value 型は Promise オブジェクト: これは通常の関数とは本質的に異なり、使用する際の注意点でもあります;

  • return newPromise( )、この使用法は一致していますasync 関数の本来の目的;
  • return data, 特にこのように書くことは Promise.resolve(data) と同等であることに注意してください。返されたデータは Promise オブジェクトにカプセル化されますが、async 関数が呼び出されるとき、戻り値のデータは単純な = では取得できません。戻り値は Promise オブジェクトであるため、このデータを取得するには .then(data => { }) を使用する必要があります。戻り値がない場合は、 Promise.resolve(unknown ); を返すのと同等
  • (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 は、非同期関数内でのみ使用できます。通常の関数内に配置することはできません。そうでない場合は、エラーが報告されます。

(2) await キーワードの後に​​ Promise オブジェクトが続きます。この関数の後に関数が続く場合、この関数は Promise オブジェクトを返す必要があります。非 Promise オブジェクトが後に続く場合、Promise.resolve() 関数を通じて自動的に Promise オブジェクトにパッケージ化され、満たされた状態になります。

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

(3) await の本質は、変更した Promise オブジェクトの満たされたステータスを待ち、resolve(data) のデータを返すことです。

は、await の後に

Promise

オブジェクトが続く場合、await は次のコードをブロックし、Promise オブジェクト を待機することを意味します。 solve を実行し、await 式の結果として resolve の値を取得します。 <pre class="brush:php;toolbar:false"> async function testAsync(){      return new Promise((resolve, reject) =&gt; {        setTimeout(function () {          resolve(&quot;成功调用testAsync&quot;)        }, 1000);      });  }    const a = await testAsync() //这里的a就会拿到testAsync函数resolve的数据  console.log(a) //在一秒后输出'成功调用testAsync'</pre> (4) await は、変更する Promise オブジェクトの拒否ステータスを気にしません。つまり、reject (data) のデータは await によって処理されないため、catch スルーを呼び出すことをお勧めします。 Promise オブジェクトを使用してキャプチャします。

 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 が呼び出された後
##非同期操作は他のコードの実行に影響を与えないため、他のコードが順番に実行され、最後に double 関数が実行されます

#ここで await キーワードが使用されているため、ここで実行すると getResult() コードがブロックされます。double 関数が解決されるまで待ってから、実行を続行してください

④尽管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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。